tiny-essentials 1.19.0 → 1.19.2
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 +75 -15
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyLocalStorage.js +76 -16
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyUploadClicker.js +75 -15
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/libs/TinyLocalStorage.cjs +75 -15
- package/dist/v1/libs/TinyLocalStorage.d.mts +20 -7
- package/dist/v1/libs/TinyLocalStorage.mjs +75 -21
- package/docs/v1/libs/TinyLocalStorage.md +23 -4
- package/package.json +1 -1
|
@@ -9,6 +9,22 @@ const customEncoders = new Map();
|
|
|
9
9
|
/** @type {Map<any, DecodeFn>} */
|
|
10
10
|
const customDecoders = new Map();
|
|
11
11
|
|
|
12
|
+
/** @type {Set<any>} */
|
|
13
|
+
const customTypesFreezed = new Set([
|
|
14
|
+
'string',
|
|
15
|
+
'boolean',
|
|
16
|
+
'number',
|
|
17
|
+
'object',
|
|
18
|
+
'array',
|
|
19
|
+
String,
|
|
20
|
+
Boolean,
|
|
21
|
+
Number,
|
|
22
|
+
Object,
|
|
23
|
+
Array,
|
|
24
|
+
BigInt,
|
|
25
|
+
Symbol,
|
|
26
|
+
]);
|
|
27
|
+
|
|
12
28
|
/**
|
|
13
29
|
* A function that encodes a value into a serializable JSON-compatible format.
|
|
14
30
|
*
|
|
@@ -280,26 +296,49 @@ class TinyLocalStorage {
|
|
|
280
296
|
|
|
281
297
|
///////////////////////////////////////////////////
|
|
282
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Checks whether a JSON-serializable type is already registered.
|
|
301
|
+
*
|
|
302
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
303
|
+
* or a reference to a class/constructor function.
|
|
304
|
+
* @returns {boolean} True if the type has both an encoder and decoder registered.
|
|
305
|
+
*/
|
|
306
|
+
static hasJsonType(type) {
|
|
307
|
+
return (customEncoders.has(type) && customDecoders.has(type)) || customTypesFreezed.has(type);
|
|
308
|
+
}
|
|
309
|
+
|
|
283
310
|
/**
|
|
284
311
|
* Registers a new JSON-serializable type with its encoder and decoder.
|
|
285
312
|
*
|
|
286
|
-
* @param {any} type - The type
|
|
287
|
-
*
|
|
288
|
-
* @param {
|
|
313
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
314
|
+
* or a reference to a class/constructor function.
|
|
315
|
+
* @param {EncodeFn} encodeFn - A function that receives a value of this type and returns a JSON-safe representation.
|
|
316
|
+
* @param {DecodeFn} decodeFn - An object with `check(value)` to identify this type and `decode(value)` to restore it.
|
|
317
|
+
* @param {boolean} [freezeType=false] - If true, prevents this type from being unregistered later.
|
|
318
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be registered.
|
|
289
319
|
*/
|
|
290
|
-
static registerJsonType(type, encodeFn, decodeFn) {
|
|
320
|
+
static registerJsonType(type, encodeFn, decodeFn, freezeType = false) {
|
|
321
|
+
if (customTypesFreezed.has(type))
|
|
322
|
+
throw new Error(`Cannot register type "${type}" because it is frozen.`);
|
|
291
323
|
customEncoders.set(type, encodeFn);
|
|
292
324
|
customDecoders.set(type, decodeFn);
|
|
325
|
+
if (freezeType) customTypesFreezed.add(type);
|
|
293
326
|
}
|
|
294
327
|
|
|
295
328
|
/**
|
|
296
|
-
*
|
|
329
|
+
* Unregisters a previously registered custom type from the encoding/decoding system.
|
|
297
330
|
*
|
|
298
|
-
* @param {
|
|
331
|
+
* @param {any} type - The primitive name or constructor reference used in the registration.
|
|
332
|
+
* @returns {boolean} Returns true if the type existed and was removed, or false if it wasn't found.
|
|
333
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be unregistered.
|
|
299
334
|
*/
|
|
300
335
|
static deleteJsonType(type) {
|
|
301
|
-
|
|
302
|
-
|
|
336
|
+
if (customTypesFreezed.has(type))
|
|
337
|
+
throw new Error(`Cannot remove type "${type}" because it is frozen.`);
|
|
338
|
+
let isDeleted = false;
|
|
339
|
+
if (customEncoders.delete(type)) isDeleted = true;
|
|
340
|
+
if (customDecoders.delete(type)) isDeleted = true;
|
|
341
|
+
return isDeleted;
|
|
303
342
|
}
|
|
304
343
|
|
|
305
344
|
//////////////////////////////////////////////////////
|
|
@@ -446,7 +485,7 @@ class TinyLocalStorage {
|
|
|
446
485
|
}
|
|
447
486
|
const encoded = this.#setJson(name, data);
|
|
448
487
|
this.emit('setJson', name, data);
|
|
449
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
488
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
450
489
|
}
|
|
451
490
|
|
|
452
491
|
/**
|
|
@@ -516,8 +555,8 @@ class TinyLocalStorage {
|
|
|
516
555
|
setDate(name, data) {
|
|
517
556
|
if (!(data instanceof Date)) throw new Error('Value must be a Date.');
|
|
518
557
|
const encoded = this.#setJson(name, data);
|
|
519
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
520
558
|
this.emit('setDate', name, data);
|
|
559
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
521
560
|
}
|
|
522
561
|
|
|
523
562
|
/**
|
|
@@ -538,8 +577,8 @@ class TinyLocalStorage {
|
|
|
538
577
|
setRegExp(name, data) {
|
|
539
578
|
if (!(data instanceof RegExp)) throw new Error('Value must be a RegExp.');
|
|
540
579
|
const encoded = this.#setJson(name, data);
|
|
541
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
542
580
|
this.emit('setRegExp', name, data);
|
|
581
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
543
582
|
}
|
|
544
583
|
|
|
545
584
|
/**
|
|
@@ -560,8 +599,8 @@ class TinyLocalStorage {
|
|
|
560
599
|
setBigInt(name, data) {
|
|
561
600
|
if (typeof data !== 'bigint') throw new Error('Value must be a BigInt.');
|
|
562
601
|
const encoded = this.#setJson(name, data);
|
|
563
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
564
602
|
this.emit('setBigInt', name, data);
|
|
603
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
565
604
|
}
|
|
566
605
|
|
|
567
606
|
/**
|
|
@@ -583,8 +622,8 @@ class TinyLocalStorage {
|
|
|
583
622
|
setSymbol(name, data) {
|
|
584
623
|
if (typeof data !== 'symbol') throw new Error('Value must be a Symbol.');
|
|
585
624
|
const encoded = this.#setJson(name, data);
|
|
586
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
587
625
|
this.emit('setSymbol', name, data);
|
|
626
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
588
627
|
}
|
|
589
628
|
|
|
590
629
|
/**
|
|
@@ -644,7 +683,13 @@ class TinyLocalStorage {
|
|
|
644
683
|
if (typeof data !== 'string') throw new Error('Value must be a string.');
|
|
645
684
|
|
|
646
685
|
this.emit('setString', name, data);
|
|
647
|
-
return this.#localStorage.setItem(
|
|
686
|
+
return this.#localStorage.setItem(
|
|
687
|
+
name,
|
|
688
|
+
JSON.stringify({
|
|
689
|
+
__string__: true,
|
|
690
|
+
value: data,
|
|
691
|
+
}),
|
|
692
|
+
);
|
|
648
693
|
}
|
|
649
694
|
|
|
650
695
|
/**
|
|
@@ -657,6 +702,15 @@ class TinyLocalStorage {
|
|
|
657
702
|
if (typeof name !== 'string' || !name.length)
|
|
658
703
|
throw new Error('Key must be a non-empty string.');
|
|
659
704
|
let value = this.#localStorage.getItem(name);
|
|
705
|
+
try {
|
|
706
|
+
/** @type {{ value: string; __string__: boolean }} */
|
|
707
|
+
// @ts-ignore
|
|
708
|
+
value = JSON.parse(value);
|
|
709
|
+
if (!objChecker.isJsonObject(value) || !value.__string__ || typeof value.value !== 'string') return null;
|
|
710
|
+
value = value.value;
|
|
711
|
+
} catch {
|
|
712
|
+
value = null;
|
|
713
|
+
}
|
|
660
714
|
if (typeof value === 'string') return value;
|
|
661
715
|
return null;
|
|
662
716
|
}
|
|
@@ -746,7 +800,7 @@ class TinyLocalStorage {
|
|
|
746
800
|
* Clears all data from `localStorage`.
|
|
747
801
|
*/
|
|
748
802
|
clearLocalStorage() {
|
|
749
|
-
this.#localStorage.clear();
|
|
803
|
+
return this.#localStorage.clear();
|
|
750
804
|
}
|
|
751
805
|
|
|
752
806
|
/**
|
|
@@ -773,6 +827,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
773
827
|
decode: (value, decodeSpecialJson) =>
|
|
774
828
|
new Map(value.data.map(([k, v]) => [k, decodeSpecialJson(v)])),
|
|
775
829
|
},
|
|
830
|
+
true,
|
|
776
831
|
);
|
|
777
832
|
|
|
778
833
|
// Set
|
|
@@ -786,6 +841,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
786
841
|
check: (value) => value.__set__,
|
|
787
842
|
decode: (value, decodeSpecialJson) => new Set(value.data.map(decodeSpecialJson)),
|
|
788
843
|
},
|
|
844
|
+
true,
|
|
789
845
|
);
|
|
790
846
|
|
|
791
847
|
// Date
|
|
@@ -799,6 +855,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
799
855
|
check: (value) => value.__date__,
|
|
800
856
|
decode: (value) => new Date(value.value),
|
|
801
857
|
},
|
|
858
|
+
true,
|
|
802
859
|
);
|
|
803
860
|
|
|
804
861
|
// Regex
|
|
@@ -813,6 +870,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
813
870
|
check: (value) => value.__regexp__,
|
|
814
871
|
decode: (value) => new RegExp(value.source, value.flags),
|
|
815
872
|
},
|
|
873
|
+
true,
|
|
816
874
|
);
|
|
817
875
|
|
|
818
876
|
// Big Int
|
|
@@ -826,6 +884,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
826
884
|
check: (value) => value.__bigint__,
|
|
827
885
|
decode: (value) => BigInt(value.value),
|
|
828
886
|
},
|
|
887
|
+
true,
|
|
829
888
|
);
|
|
830
889
|
|
|
831
890
|
// Symbol
|
|
@@ -842,6 +901,7 @@ TinyLocalStorage.registerJsonType(
|
|
|
842
901
|
return key != null ? Symbol.for(key) : Symbol();
|
|
843
902
|
},
|
|
844
903
|
},
|
|
904
|
+
true,
|
|
845
905
|
);
|
|
846
906
|
|
|
847
907
|
module.exports = TinyLocalStorage;
|
|
@@ -101,20 +101,33 @@ export type LocalStorageJsonValue = (Record<string | number | symbol, any> | any
|
|
|
101
101
|
* This class is suitable for applications that require structured persistence in the browser.
|
|
102
102
|
*/
|
|
103
103
|
declare class TinyLocalStorage {
|
|
104
|
+
/**
|
|
105
|
+
* Checks whether a JSON-serializable type is already registered.
|
|
106
|
+
*
|
|
107
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
108
|
+
* or a reference to a class/constructor function.
|
|
109
|
+
* @returns {boolean} True if the type has both an encoder and decoder registered.
|
|
110
|
+
*/
|
|
111
|
+
static hasJsonType(type: any): boolean;
|
|
104
112
|
/**
|
|
105
113
|
* Registers a new JSON-serializable type with its encoder and decoder.
|
|
106
114
|
*
|
|
107
|
-
* @param {any} type - The type
|
|
108
|
-
*
|
|
109
|
-
* @param {
|
|
115
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
116
|
+
* or a reference to a class/constructor function.
|
|
117
|
+
* @param {EncodeFn} encodeFn - A function that receives a value of this type and returns a JSON-safe representation.
|
|
118
|
+
* @param {DecodeFn} decodeFn - An object with `check(value)` to identify this type and `decode(value)` to restore it.
|
|
119
|
+
* @param {boolean} [freezeType=false] - If true, prevents this type from being unregistered later.
|
|
120
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be registered.
|
|
110
121
|
*/
|
|
111
|
-
static registerJsonType(type: any, encodeFn: EncodeFn, decodeFn: DecodeFn): void;
|
|
122
|
+
static registerJsonType(type: any, encodeFn: EncodeFn, decodeFn: DecodeFn, freezeType?: boolean): void;
|
|
112
123
|
/**
|
|
113
|
-
*
|
|
124
|
+
* Unregisters a previously registered custom type from the encoding/decoding system.
|
|
114
125
|
*
|
|
115
|
-
* @param {
|
|
126
|
+
* @param {any} type - The primitive name or constructor reference used in the registration.
|
|
127
|
+
* @returns {boolean} Returns true if the type existed and was removed, or false if it wasn't found.
|
|
128
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be unregistered.
|
|
116
129
|
*/
|
|
117
|
-
static deleteJsonType(type:
|
|
130
|
+
static deleteJsonType(type: any): boolean;
|
|
118
131
|
static encodeSpecialJson(value: any): any;
|
|
119
132
|
static decodeSpecialJson(value: any): any;
|
|
120
133
|
/**
|
|
@@ -4,6 +4,21 @@ import TinyEvents from './TinyEvents.mjs';
|
|
|
4
4
|
const customEncoders = new Map();
|
|
5
5
|
/** @type {Map<any, DecodeFn>} */
|
|
6
6
|
const customDecoders = new Map();
|
|
7
|
+
/** @type {Set<any>} */
|
|
8
|
+
const customTypesFreezed = new Set([
|
|
9
|
+
'string',
|
|
10
|
+
'boolean',
|
|
11
|
+
'number',
|
|
12
|
+
'object',
|
|
13
|
+
'array',
|
|
14
|
+
String,
|
|
15
|
+
Boolean,
|
|
16
|
+
Number,
|
|
17
|
+
Object,
|
|
18
|
+
Array,
|
|
19
|
+
BigInt,
|
|
20
|
+
Symbol,
|
|
21
|
+
]);
|
|
7
22
|
/**
|
|
8
23
|
* A function that encodes a value into a serializable JSON-compatible format.
|
|
9
24
|
*
|
|
@@ -243,25 +258,50 @@ class TinyLocalStorage {
|
|
|
243
258
|
return this.#events.getMaxListeners();
|
|
244
259
|
}
|
|
245
260
|
///////////////////////////////////////////////////
|
|
261
|
+
/**
|
|
262
|
+
* Checks whether a JSON-serializable type is already registered.
|
|
263
|
+
*
|
|
264
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
265
|
+
* or a reference to a class/constructor function.
|
|
266
|
+
* @returns {boolean} True if the type has both an encoder and decoder registered.
|
|
267
|
+
*/
|
|
268
|
+
static hasJsonType(type) {
|
|
269
|
+
return (customEncoders.has(type) && customDecoders.has(type)) || customTypesFreezed.has(type);
|
|
270
|
+
}
|
|
246
271
|
/**
|
|
247
272
|
* Registers a new JSON-serializable type with its encoder and decoder.
|
|
248
273
|
*
|
|
249
|
-
* @param {any} type - The type
|
|
250
|
-
*
|
|
251
|
-
* @param {
|
|
274
|
+
* @param {any} type - The type identifier, which can be a string (e.g., `"bigint"`, `"symbol"`)
|
|
275
|
+
* or a reference to a class/constructor function.
|
|
276
|
+
* @param {EncodeFn} encodeFn - A function that receives a value of this type and returns a JSON-safe representation.
|
|
277
|
+
* @param {DecodeFn} decodeFn - An object with `check(value)` to identify this type and `decode(value)` to restore it.
|
|
278
|
+
* @param {boolean} [freezeType=false] - If true, prevents this type from being unregistered later.
|
|
279
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be registered.
|
|
252
280
|
*/
|
|
253
|
-
static registerJsonType(type, encodeFn, decodeFn) {
|
|
281
|
+
static registerJsonType(type, encodeFn, decodeFn, freezeType = false) {
|
|
282
|
+
if (customTypesFreezed.has(type))
|
|
283
|
+
throw new Error(`Cannot register type "${type}" because it is frozen.`);
|
|
254
284
|
customEncoders.set(type, encodeFn);
|
|
255
285
|
customDecoders.set(type, decodeFn);
|
|
286
|
+
if (freezeType)
|
|
287
|
+
customTypesFreezed.add(type);
|
|
256
288
|
}
|
|
257
289
|
/**
|
|
258
|
-
*
|
|
290
|
+
* Unregisters a previously registered custom type from the encoding/decoding system.
|
|
259
291
|
*
|
|
260
|
-
* @param {
|
|
292
|
+
* @param {any} type - The primitive name or constructor reference used in the registration.
|
|
293
|
+
* @returns {boolean} Returns true if the type existed and was removed, or false if it wasn't found.
|
|
294
|
+
* @throws {Error} Throws an error if the type is frozen and cannot be unregistered.
|
|
261
295
|
*/
|
|
262
296
|
static deleteJsonType(type) {
|
|
263
|
-
|
|
264
|
-
|
|
297
|
+
if (customTypesFreezed.has(type))
|
|
298
|
+
throw new Error(`Cannot remove type "${type}" because it is frozen.`);
|
|
299
|
+
let isDeleted = false;
|
|
300
|
+
if (customEncoders.delete(type))
|
|
301
|
+
isDeleted = true;
|
|
302
|
+
if (customDecoders.delete(type))
|
|
303
|
+
isDeleted = true;
|
|
304
|
+
return isDeleted;
|
|
265
305
|
}
|
|
266
306
|
//////////////////////////////////////////////////////
|
|
267
307
|
/**
|
|
@@ -392,7 +432,7 @@ class TinyLocalStorage {
|
|
|
392
432
|
}
|
|
393
433
|
const encoded = this.#setJson(name, data);
|
|
394
434
|
this.emit('setJson', name, data);
|
|
395
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
435
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
396
436
|
}
|
|
397
437
|
/**
|
|
398
438
|
* Retrieves a value from `localStorage`.
|
|
@@ -454,8 +494,8 @@ class TinyLocalStorage {
|
|
|
454
494
|
if (!(data instanceof Date))
|
|
455
495
|
throw new Error('Value must be a Date.');
|
|
456
496
|
const encoded = this.#setJson(name, data);
|
|
457
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
458
497
|
this.emit('setDate', name, data);
|
|
498
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
459
499
|
}
|
|
460
500
|
/**
|
|
461
501
|
* Retrieves a Date from localStorage.
|
|
@@ -475,8 +515,8 @@ class TinyLocalStorage {
|
|
|
475
515
|
if (!(data instanceof RegExp))
|
|
476
516
|
throw new Error('Value must be a RegExp.');
|
|
477
517
|
const encoded = this.#setJson(name, data);
|
|
478
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
479
518
|
this.emit('setRegExp', name, data);
|
|
519
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
480
520
|
}
|
|
481
521
|
/**
|
|
482
522
|
* Retrieves a RegExp from localStorage.
|
|
@@ -496,8 +536,8 @@ class TinyLocalStorage {
|
|
|
496
536
|
if (typeof data !== 'bigint')
|
|
497
537
|
throw new Error('Value must be a BigInt.');
|
|
498
538
|
const encoded = this.#setJson(name, data);
|
|
499
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
500
539
|
this.emit('setBigInt', name, data);
|
|
540
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
501
541
|
}
|
|
502
542
|
/**
|
|
503
543
|
* Retrieves a BigInt from localStorage.
|
|
@@ -518,8 +558,8 @@ class TinyLocalStorage {
|
|
|
518
558
|
if (typeof data !== 'symbol')
|
|
519
559
|
throw new Error('Value must be a Symbol.');
|
|
520
560
|
const encoded = this.#setJson(name, data);
|
|
521
|
-
this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
522
561
|
this.emit('setSymbol', name, data);
|
|
562
|
+
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
523
563
|
}
|
|
524
564
|
/**
|
|
525
565
|
* Retrieves a Symbol from localStorage.
|
|
@@ -574,7 +614,10 @@ class TinyLocalStorage {
|
|
|
574
614
|
if (typeof data !== 'string')
|
|
575
615
|
throw new Error('Value must be a string.');
|
|
576
616
|
this.emit('setString', name, data);
|
|
577
|
-
return this.#localStorage.setItem(name,
|
|
617
|
+
return this.#localStorage.setItem(name, JSON.stringify({
|
|
618
|
+
__string__: true,
|
|
619
|
+
value: data,
|
|
620
|
+
}));
|
|
578
621
|
}
|
|
579
622
|
/**
|
|
580
623
|
* Retrieves a string value from `localStorage`.
|
|
@@ -586,6 +629,17 @@ class TinyLocalStorage {
|
|
|
586
629
|
if (typeof name !== 'string' || !name.length)
|
|
587
630
|
throw new Error('Key must be a non-empty string.');
|
|
588
631
|
let value = this.#localStorage.getItem(name);
|
|
632
|
+
try {
|
|
633
|
+
/** @type {{ value: string; __string__: boolean }} */
|
|
634
|
+
// @ts-ignore
|
|
635
|
+
value = JSON.parse(value);
|
|
636
|
+
if (!isJsonObject(value) || !value.__string__ || typeof value.value !== 'string')
|
|
637
|
+
return null;
|
|
638
|
+
value = value.value;
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
value = null;
|
|
642
|
+
}
|
|
589
643
|
if (typeof value === 'string')
|
|
590
644
|
return value;
|
|
591
645
|
return null;
|
|
@@ -673,7 +727,7 @@ class TinyLocalStorage {
|
|
|
673
727
|
* Clears all data from `localStorage`.
|
|
674
728
|
*/
|
|
675
729
|
clearLocalStorage() {
|
|
676
|
-
this.#localStorage.clear();
|
|
730
|
+
return this.#localStorage.clear();
|
|
677
731
|
}
|
|
678
732
|
/**
|
|
679
733
|
* Destroys the storage instance by removing the storage event listener.
|
|
@@ -692,7 +746,7 @@ TinyLocalStorage.registerJsonType(Map, (value, encodeSpecialJson) => ({
|
|
|
692
746
|
check: (value) => value.__map__,
|
|
693
747
|
/** @param {{ data: any[] }} value */
|
|
694
748
|
decode: (value, decodeSpecialJson) => new Map(value.data.map(([k, v]) => [k, decodeSpecialJson(v)])),
|
|
695
|
-
});
|
|
749
|
+
}, true);
|
|
696
750
|
// Set
|
|
697
751
|
TinyLocalStorage.registerJsonType(Set, (value, encodeSpecialJson) => ({
|
|
698
752
|
__set__: true,
|
|
@@ -700,7 +754,7 @@ TinyLocalStorage.registerJsonType(Set, (value, encodeSpecialJson) => ({
|
|
|
700
754
|
}), {
|
|
701
755
|
check: (value) => value.__set__,
|
|
702
756
|
decode: (value, decodeSpecialJson) => new Set(value.data.map(decodeSpecialJson)),
|
|
703
|
-
});
|
|
757
|
+
}, true);
|
|
704
758
|
// Date
|
|
705
759
|
TinyLocalStorage.registerJsonType(Date, (value) => ({
|
|
706
760
|
__date__: true,
|
|
@@ -708,7 +762,7 @@ TinyLocalStorage.registerJsonType(Date, (value) => ({
|
|
|
708
762
|
}), {
|
|
709
763
|
check: (value) => value.__date__,
|
|
710
764
|
decode: (value) => new Date(value.value),
|
|
711
|
-
});
|
|
765
|
+
}, true);
|
|
712
766
|
// Regex
|
|
713
767
|
TinyLocalStorage.registerJsonType(RegExp, (value) => ({
|
|
714
768
|
__regexp__: true,
|
|
@@ -717,7 +771,7 @@ TinyLocalStorage.registerJsonType(RegExp, (value) => ({
|
|
|
717
771
|
}), {
|
|
718
772
|
check: (value) => value.__regexp__,
|
|
719
773
|
decode: (value) => new RegExp(value.source, value.flags),
|
|
720
|
-
});
|
|
774
|
+
}, true);
|
|
721
775
|
// Big Int
|
|
722
776
|
TinyLocalStorage.registerJsonType('bigint', (value) => ({
|
|
723
777
|
__bigint__: true,
|
|
@@ -725,7 +779,7 @@ TinyLocalStorage.registerJsonType('bigint', (value) => ({
|
|
|
725
779
|
}), {
|
|
726
780
|
check: (value) => value.__bigint__,
|
|
727
781
|
decode: (value) => BigInt(value.value),
|
|
728
|
-
});
|
|
782
|
+
}, true);
|
|
729
783
|
// Symbol
|
|
730
784
|
TinyLocalStorage.registerJsonType('symbol', (value) => ({
|
|
731
785
|
__symbol__: true,
|
|
@@ -736,5 +790,5 @@ TinyLocalStorage.registerJsonType('symbol', (value) => ({
|
|
|
736
790
|
const key = value.key;
|
|
737
791
|
return key != null ? Symbol.for(key) : Symbol();
|
|
738
792
|
},
|
|
739
|
-
});
|
|
793
|
+
}, true);
|
|
740
794
|
export default TinyLocalStorage;
|
|
@@ -243,7 +243,7 @@ Returns `true` if the browser supports the configured storage backend.
|
|
|
243
243
|
|
|
244
244
|
## 🧩 Custom Type Registration
|
|
245
245
|
|
|
246
|
-
### `registerJsonType(type, encodeFn, decodeFn)`
|
|
246
|
+
### `registerJsonType(type, encodeFn, decodeFn, freezeType?)`
|
|
247
247
|
|
|
248
248
|
Registers support for custom types with encoder/decoder logic.
|
|
249
249
|
|
|
@@ -254,10 +254,15 @@ registerJsonType(
|
|
|
254
254
|
decodeFn: {
|
|
255
255
|
check: (value: any) => boolean,
|
|
256
256
|
decode: (value: any, decodeSpecialJson: DecodeFn) => any
|
|
257
|
-
}
|
|
257
|
+
},
|
|
258
|
+
freezeType?: boolean // default: false
|
|
258
259
|
): void
|
|
259
260
|
```
|
|
260
261
|
|
|
262
|
+
Registers a custom type by associating it with encoder and decoder logic. If `freezeType` is set to `true`, the type becomes immutable and cannot be unregistered or overwritten later.
|
|
263
|
+
|
|
264
|
+
> ⚠️ Throws an error if trying to register a type that is already frozen.
|
|
265
|
+
|
|
261
266
|
---
|
|
262
267
|
|
|
263
268
|
### `deleteJsonType(type)`
|
|
@@ -265,10 +270,24 @@ registerJsonType(
|
|
|
265
270
|
Unregisters a previously registered custom type.
|
|
266
271
|
|
|
267
272
|
```ts
|
|
268
|
-
deleteJsonType(type: any):
|
|
273
|
+
deleteJsonType(type: any): boolean
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Removes the encoder and decoder associated with the given type. Returns `true` if the type was found and removed, or `false` if it was not registered.
|
|
277
|
+
|
|
278
|
+
> ❌ Throws an error if the type was marked as frozen via `freezeType`.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### `hasJsonType(type)`
|
|
283
|
+
|
|
284
|
+
Checks whether a type is currently registered for custom encoding/decoding.
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
hasJsonType(type: any): boolean
|
|
269
288
|
```
|
|
270
289
|
|
|
271
|
-
|
|
290
|
+
Returns `true` if the type has both encoder and decoder registered, otherwise `false`.
|
|
272
291
|
|
|
273
292
|
---
|
|
274
293
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-essentials",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.2",
|
|
4
4
|
"description": "Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "npm run test:mjs && npm run test:cjs && npm run test:js",
|