tiny-essentials 1.19.2 → 1.20.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/dist/v1/TinyEssentials.js +1009 -22
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyIframeEvents.js +854 -0
- package/dist/v1/TinyIframeEvents.min.js +1 -0
- package/dist/v1/TinyLocalStorage.js +109 -21
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.js +888 -0
- package/dist/v1/TinyNewWinEvents.min.js +1 -0
- package/dist/v1/TinyUploadClicker.js +1022 -37
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/build/TinyIframeEvents.cjs +7 -0
- package/dist/v1/build/TinyIframeEvents.d.mts +3 -0
- package/dist/v1/build/TinyIframeEvents.mjs +2 -0
- package/dist/v1/build/TinyNewWinEvents.cjs +7 -0
- package/dist/v1/build/TinyNewWinEvents.d.mts +3 -0
- package/dist/v1/build/TinyNewWinEvents.mjs +2 -0
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +3 -1
- package/dist/v1/index.mjs +3 -1
- package/dist/v1/libs/TinyIframeEvents.cjs +409 -0
- package/dist/v1/libs/TinyIframeEvents.d.mts +193 -0
- package/dist/v1/libs/TinyIframeEvents.mjs +348 -0
- 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/dist/v1/libs/TinyNewWinEvents.cjs +486 -0
- package/dist/v1/libs/TinyNewWinEvents.d.mts +241 -0
- package/dist/v1/libs/TinyNewWinEvents.mjs +437 -0
- package/docs/v1/README.md +2 -0
- package/docs/v1/libs/TinyIframeEvents.md +149 -0
- package/docs/v1/libs/TinyLocalStorage.md +53 -0
- package/docs/v1/libs/TinyNewWinEvents.md +186 -0
- package/docs/v1/libs/TinyNotifyCenter.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{"use strict";var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyIframeEvents:()=>s});const n=class{#e=new Map;#t=10;#n=!1;setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#n=e}getThrowOnMaxListeners(){return this.#n}#r(e,t,{once:n=!1}={}){let r=this.#e.get(e);Array.isArray(r)||(r=[],this.#e.set(e,r)),r.unshift({handler:t,config:{once:n}});const s=this.#t;if(s>0&&r.length>s){const t=`Possible memory leak detected. ${r.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}prependListener(e,t){if("string"!=typeof e)throw new TypeError("prepend(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prepend(event, handler): handler must be a function");this.#r(e,t)}prependListenerOnce(e,t){if("string"!=typeof e)throw new TypeError("prependOnceListener(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prependOnceListener(event, handler): handler must be a function");const n=(...r)=>{this.off(e,n),t(...r)};return this.#r(e,n,{once:!0}),n}#s(e,t,{once:n=!1}={}){let r=this.#e.get(e);Array.isArray(r)||(r=[],this.#e.set(e,r)),r.push({handler:t,config:{once:n}});const s=this.#t;if(s>0&&r.length>s){const t=`Possible memory leak detected. ${r.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#n)throw new Error(t);console.warn(t)}}on(e,t){if("string"!=typeof e)throw new TypeError("on(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#s(e,t)}once(e,t){if("string"!=typeof e)throw new TypeError("The event name must be a string.");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const n=r=>{this.off(e,n),"function"==typeof t&&t(r)};return this.#s(e,n,{once:!0}),n}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){if("string"!=typeof e)throw new TypeError("off(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");const n=this.#e.get(e);if(!Array.isArray(n))return;const r=n.findIndex(e=>e.handler===t);-1!==r&&n.splice(r,1),0===n.length&&this.#e.delete(e)}offAll(e){if("string"!=typeof e)throw new TypeError("The event name must be a string.");this.#e.delete(e)}offAllTypes(){this.#e.clear()}listenerCount(e){if("string"!=typeof e)throw new TypeError("listenerCount(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?t.length:0}listeners(e){if("string"!=typeof e)throw new TypeError("listeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>!e.config.once).map(e=>e.handler):[]}onceListeners(e){if("string"!=typeof e)throw new TypeError("onceListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>e.config.once).map(e=>e.handler):[]}allListeners(e){if("string"!=typeof e)throw new TypeError("allListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].map(e=>e.handler):[]}eventNames(){return[...this.#e.keys()]}emit(e,...t){if("string"!=typeof e)throw new TypeError("emit(event, data): event name must be a string");const n=this.#e.get(e);return!(!Array.isArray(n)||0===n.length||(n.forEach(e=>e.handler(...t)),0))}setMaxListeners(e){if(!Number.isInteger(e)||e<0)throw new TypeError("setMaxListeners(n): n must be a non-negative integer");this.#t=e}getMaxListeners(){return this.#t}},r=new WeakMap,s=class{#i=new n;setThrowOnMaxListeners(e){return this.#i.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#i.getThrowOnMaxListeners()}prependListener(e,t){return this.#i.prependListener(e,t)}prependListenerOnce(e,t){return this.#i.prependListenerOnce(e,t)}appendListener(e,t){return this.#i.appendListener(e,t)}appendListenerOnce(e,t){return this.#i.appendListenerOnce(e,t)}on(e,t){return this.#i.on(e,t)}once(e,t){return this.#i.once(e,t)}off(e,t){return this.#i.off(e,t)}offAll(e){return this.#i.offAll(e)}offAllTypes(){return this.#i.offAllTypes()}listenerCount(e){return this.#i.listenerCount(e)}listeners(e){return this.#i.listeners(e)}onceListeners(e){return this.#i.onceListeners(e)}allListeners(e){return this.#i.allListeners(e)}eventNames(){return this.#i.eventNames()}setMaxListeners(e){return this.#i.setMaxListeners(e)}getMaxListeners(){return this.#i.getMaxListeners()}#o;#a;#h;#d=!1;#f=!1;#p=[];#l="__tinyIframeEvent__";get secretEventName(){return this.#l}set secretEventName(e){if("string"!=typeof e)throw new TypeError("TinyIframeEvents: secretEventName must be a string.");this.#l=e}constructor({targetIframe:e,targetOrigin:t}={}){if(!(void 0===e||e instanceof HTMLIFrameElement&&e.contentWindow))throw new TypeError('[TinyIframeEvents] Invalid "targetIframe" provided: expected a HTML Iframe Element, received '+typeof e);if(void 0!==t&&"string"!=typeof t)throw new TypeError('[TinyIframeEvents] Invalid "targetOrigin" provided: expected a string, received '+typeof t);if(this.#o=e?.contentWindow??window.parent,this.#a=t??window.location.origin,this.#h=e?"parent":"iframe",r.has(this.#o))throw new Error("Duplicate window reference.");this._boundOnMessage=this.#c.bind(this),this._boundOnceMessage=this.#g.bind(this),"complete"===this.#o.document.readyState||"interactive"===this.#o.document.readyState?this.#g():(this.#o.addEventListener("load",this._boundOnceMessage,!1),this.#o.addEventListener("DOMContentLoaded",this._boundOnceMessage,!1)),window.addEventListener("message",this._boundOnMessage,!1),r.set(this.#o,this)}#g(){this.#f||(this.#f=!0,this.#u())}#c(e){const{data:t,source:n}=e;if(null===(r=t)||"object"!=typeof r||Array.isArray(r)||"[object Object]"!==Object.prototype.toString.call(r)||!t[this.#l])return;var r;const{eventName:s,payload:i,direction:o}=t;n===this.#o&&("iframe"===this.#h&&"iframe"!==o||"parent"===this.#h&&"parent"!==o||this.#i.emit(s,i,e))}emit(e,t){if("string"!=typeof e)throw new TypeError("Event name must be a string.");if(this.#d)throw new Error("Cannot emit: instance has been destroyed.");const n={[this.#l]:!0,eventName:e,payload:t,direction:"parent"===this.#h?"iframe":"parent"};this.#f?this.#o.postMessage(n,this.#a):this.#p.push(n)}#u(){for(;this.#p.length;){const e=this.#p.shift();e&&this.#o.postMessage(e,this.#a)}}isDestroyed(){return this.#d}destroy(){this.#d=!0,window.removeEventListener("message",this._boundOnMessage),this.#o.removeEventListener("load",this._boundOnceMessage,!1),this.#o.removeEventListener("DOMContentLoaded",this._boundOnceMessage,!1),this.#i.offAllTypes(),this.#p=[],r.delete(this.#o)}};window.TinyIframeEvents=t.TinyIframeEvents})();
|
|
@@ -857,6 +857,12 @@ class TinyLocalStorage {
|
|
|
857
857
|
/** @type {Storage} */
|
|
858
858
|
#localStorage = window.localStorage;
|
|
859
859
|
|
|
860
|
+
/** @type {string|null} */
|
|
861
|
+
#dbKey = null;
|
|
862
|
+
|
|
863
|
+
/** @type {number} */
|
|
864
|
+
#version = 0;
|
|
865
|
+
|
|
860
866
|
/** @type {(ev: StorageEvent) => any} */
|
|
861
867
|
#storageEvent = (ev) => this.emit('storage', ev);
|
|
862
868
|
|
|
@@ -864,11 +870,84 @@ class TinyLocalStorage {
|
|
|
864
870
|
* Initializes the TinyLocalStorage instance and sets up cross-tab sync.
|
|
865
871
|
*
|
|
866
872
|
* Adds listener for the native `storage` event to support tab synchronization.
|
|
873
|
+
* @param {string} [dbName] - Unique database name.
|
|
867
874
|
*/
|
|
868
|
-
constructor() {
|
|
875
|
+
constructor(dbName) {
|
|
876
|
+
if (typeof dbName !== 'undefined' && typeof dbName !== 'string')
|
|
877
|
+
throw new TypeError('TinyLocalStorage: dbName must be a string if provided.');
|
|
878
|
+
if (typeof dbName === 'string') this.#dbKey = `LSDB::${dbName}`;
|
|
869
879
|
window.addEventListener('storage', this.#storageEvent);
|
|
870
880
|
}
|
|
871
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Validates that a given key does not conflict with internal database keys.
|
|
884
|
+
*
|
|
885
|
+
* This method is used to prevent accidental overwriting of reserved `LSDB::` keys
|
|
886
|
+
* in `localStorage`, which are used internally by TinyLocalStorage for versioning
|
|
887
|
+
* and data management.
|
|
888
|
+
*
|
|
889
|
+
* @param {string} name - The key to validate before writing to localStorage.
|
|
890
|
+
* @throws {Error} If the key starts with `LSDB::`.
|
|
891
|
+
*/
|
|
892
|
+
#isProtectedDbKey(name) {
|
|
893
|
+
if (typeof name === 'string' && name.startsWith('LSDB::'))
|
|
894
|
+
throw new Error(`TinyLocalStorage: Key "${name}" may conflict with reserved dbKeys.`);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Updates the version of the storage and triggers migration if needed.
|
|
899
|
+
*
|
|
900
|
+
* @param {number} version - Desired version of the database.
|
|
901
|
+
* @param {(oldVersion: number, newVersion: number) => void} onUpgrade - Callback to perform migration logic.
|
|
902
|
+
* @throws {Error} If the database key has not been initialized.
|
|
903
|
+
* @throws {TypeError} If `version` is not a valid positive number.
|
|
904
|
+
* @throws {TypeError} If `onUpgrade` is not a function.
|
|
905
|
+
*/
|
|
906
|
+
updateStorageVersion(version, onUpgrade) {
|
|
907
|
+
if (typeof this.#dbKey !== 'string')
|
|
908
|
+
throw new Error(
|
|
909
|
+
'TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.',
|
|
910
|
+
);
|
|
911
|
+
if (typeof version !== 'number' || Number.isNaN(version) || version < 1)
|
|
912
|
+
throw new TypeError('TinyLocalStorage: version must be a positive number.');
|
|
913
|
+
if (typeof onUpgrade !== 'function')
|
|
914
|
+
throw new TypeError('TinyLocalStorage: onUpgrade must be a function.');
|
|
915
|
+
|
|
916
|
+
// @ts-ignore
|
|
917
|
+
const savedVersion = parseInt(localStorage.getItem(this.#dbKey), 10) || 0;
|
|
918
|
+
if (typeof savedVersion !== 'number' || Number.isNaN(savedVersion) || savedVersion < 0)
|
|
919
|
+
throw new TypeError('TinyLocalStorage: saved version in localStorage is not a valid number.');
|
|
920
|
+
|
|
921
|
+
if (version < savedVersion)
|
|
922
|
+
throw new Error(
|
|
923
|
+
`TinyLocalStorage: Cannot downgrade database version from ${savedVersion} to ${version}.`,
|
|
924
|
+
);
|
|
925
|
+
|
|
926
|
+
if (version > savedVersion) {
|
|
927
|
+
onUpgrade(savedVersion, version);
|
|
928
|
+
localStorage.setItem(this.#dbKey, String(version));
|
|
929
|
+
this.#version = version;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Gets the current database key used in localStorage.
|
|
935
|
+
*
|
|
936
|
+
* @returns {string|null} The database key, or null if not set.
|
|
937
|
+
*/
|
|
938
|
+
getDbKey() {
|
|
939
|
+
return this.#dbKey;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* Gets the current version of the database.
|
|
944
|
+
*
|
|
945
|
+
* @returns {number} The current version number.
|
|
946
|
+
*/
|
|
947
|
+
getVersion() {
|
|
948
|
+
return this.#version;
|
|
949
|
+
}
|
|
950
|
+
|
|
872
951
|
/**
|
|
873
952
|
* Defines a custom storage interface (e.g. `sessionStorage`).
|
|
874
953
|
*
|
|
@@ -876,7 +955,7 @@ class TinyLocalStorage {
|
|
|
876
955
|
*/
|
|
877
956
|
setLocalStorage(localstorage) {
|
|
878
957
|
if (!(localstorage instanceof Storage))
|
|
879
|
-
throw new
|
|
958
|
+
throw new TypeError('Argument must be a valid instance of Storage.');
|
|
880
959
|
this.#localStorage = localstorage;
|
|
881
960
|
}
|
|
882
961
|
|
|
@@ -898,7 +977,7 @@ class TinyLocalStorage {
|
|
|
898
977
|
*/
|
|
899
978
|
#setJson(name, data) {
|
|
900
979
|
if (typeof name !== 'string' || !name.length)
|
|
901
|
-
throw new
|
|
980
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
902
981
|
return TinyLocalStorage.encodeSpecialJson(data);
|
|
903
982
|
}
|
|
904
983
|
|
|
@@ -911,13 +990,14 @@ class TinyLocalStorage {
|
|
|
911
990
|
* @param {LocalStorageJsonValue} data - The data to be serialized and stored.
|
|
912
991
|
*/
|
|
913
992
|
setJson(name, data) {
|
|
993
|
+
this.#isProtectedDbKey(name);
|
|
914
994
|
if (
|
|
915
995
|
!isJsonObject(data) &&
|
|
916
996
|
!Array.isArray(data) &&
|
|
917
997
|
!(data instanceof Map) &&
|
|
918
998
|
!(data instanceof Set)
|
|
919
999
|
) {
|
|
920
|
-
throw new
|
|
1000
|
+
throw new TypeError('The storage value is not a valid JSON-compatible structure.');
|
|
921
1001
|
}
|
|
922
1002
|
const encoded = this.#setJson(name, data);
|
|
923
1003
|
this.emit('setJson', name, data);
|
|
@@ -935,7 +1015,7 @@ class TinyLocalStorage {
|
|
|
935
1015
|
*/
|
|
936
1016
|
#getJson(name, defaultData) {
|
|
937
1017
|
if (typeof name !== 'string' || !name.length)
|
|
938
|
-
throw new
|
|
1018
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
939
1019
|
|
|
940
1020
|
const raw = this.#localStorage.getItem(name);
|
|
941
1021
|
const fallbackTypes = {
|
|
@@ -989,7 +1069,8 @@ class TinyLocalStorage {
|
|
|
989
1069
|
* @param {Date} data
|
|
990
1070
|
*/
|
|
991
1071
|
setDate(name, data) {
|
|
992
|
-
|
|
1072
|
+
this.#isProtectedDbKey(name);
|
|
1073
|
+
if (!(data instanceof Date)) throw new TypeError('Value must be a Date.');
|
|
993
1074
|
const encoded = this.#setJson(name, data);
|
|
994
1075
|
this.emit('setDate', name, data);
|
|
995
1076
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -1011,7 +1092,8 @@ class TinyLocalStorage {
|
|
|
1011
1092
|
* @param {RegExp} data
|
|
1012
1093
|
*/
|
|
1013
1094
|
setRegExp(name, data) {
|
|
1014
|
-
|
|
1095
|
+
this.#isProtectedDbKey(name);
|
|
1096
|
+
if (!(data instanceof RegExp)) throw new TypeError('Value must be a RegExp.');
|
|
1015
1097
|
const encoded = this.#setJson(name, data);
|
|
1016
1098
|
this.emit('setRegExp', name, data);
|
|
1017
1099
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -1033,7 +1115,8 @@ class TinyLocalStorage {
|
|
|
1033
1115
|
* @param {bigint} data
|
|
1034
1116
|
*/
|
|
1035
1117
|
setBigInt(name, data) {
|
|
1036
|
-
|
|
1118
|
+
this.#isProtectedDbKey(name);
|
|
1119
|
+
if (typeof data !== 'bigint') throw new TypeError('Value must be a BigInt.');
|
|
1037
1120
|
const encoded = this.#setJson(name, data);
|
|
1038
1121
|
this.emit('setBigInt', name, data);
|
|
1039
1122
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -1056,7 +1139,8 @@ class TinyLocalStorage {
|
|
|
1056
1139
|
* @param {symbol} data
|
|
1057
1140
|
*/
|
|
1058
1141
|
setSymbol(name, data) {
|
|
1059
|
-
|
|
1142
|
+
this.#isProtectedDbKey(name);
|
|
1143
|
+
if (typeof data !== 'symbol') throw new TypeError('Value must be a Symbol.');
|
|
1060
1144
|
const encoded = this.#setJson(name, data);
|
|
1061
1145
|
this.emit('setSymbol', name, data);
|
|
1062
1146
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -1089,8 +1173,9 @@ class TinyLocalStorage {
|
|
|
1089
1173
|
* @param {any} data - The data to store.
|
|
1090
1174
|
*/
|
|
1091
1175
|
setItem(name, data) {
|
|
1176
|
+
this.#isProtectedDbKey(name);
|
|
1092
1177
|
if (typeof name !== 'string' || !name.length)
|
|
1093
|
-
throw new
|
|
1178
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1094
1179
|
this.emit('setItem', name, data);
|
|
1095
1180
|
return this.#localStorage.setItem(name, data);
|
|
1096
1181
|
}
|
|
@@ -1103,7 +1188,7 @@ class TinyLocalStorage {
|
|
|
1103
1188
|
*/
|
|
1104
1189
|
getItem(name) {
|
|
1105
1190
|
if (typeof name !== 'string' || !name.length)
|
|
1106
|
-
throw new
|
|
1191
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1107
1192
|
return this.#localStorage.getItem(name);
|
|
1108
1193
|
}
|
|
1109
1194
|
|
|
@@ -1114,9 +1199,10 @@ class TinyLocalStorage {
|
|
|
1114
1199
|
* @param {string} data - The string to store.
|
|
1115
1200
|
*/
|
|
1116
1201
|
setString(name, data) {
|
|
1202
|
+
this.#isProtectedDbKey(name);
|
|
1117
1203
|
if (typeof name !== 'string' || !name.length)
|
|
1118
|
-
throw new
|
|
1119
|
-
if (typeof data !== 'string') throw new
|
|
1204
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1205
|
+
if (typeof data !== 'string') throw new TypeError('Value must be a string.');
|
|
1120
1206
|
|
|
1121
1207
|
this.emit('setString', name, data);
|
|
1122
1208
|
return this.#localStorage.setItem(
|
|
@@ -1136,7 +1222,7 @@ class TinyLocalStorage {
|
|
|
1136
1222
|
*/
|
|
1137
1223
|
getString(name) {
|
|
1138
1224
|
if (typeof name !== 'string' || !name.length)
|
|
1139
|
-
throw new
|
|
1225
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1140
1226
|
let value = this.#localStorage.getItem(name);
|
|
1141
1227
|
try {
|
|
1142
1228
|
/** @type {{ value: string; __string__: boolean }} */
|
|
@@ -1158,9 +1244,10 @@ class TinyLocalStorage {
|
|
|
1158
1244
|
* @param {number} data - The number to store.
|
|
1159
1245
|
*/
|
|
1160
1246
|
setNumber(name, data) {
|
|
1247
|
+
this.#isProtectedDbKey(name);
|
|
1161
1248
|
if (typeof name !== 'string' || !name.length)
|
|
1162
|
-
throw new
|
|
1163
|
-
if (typeof data !== 'number') throw new
|
|
1249
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1250
|
+
if (typeof data !== 'number') throw new TypeError('Value must be a number.');
|
|
1164
1251
|
this.emit('setNumber', name, data);
|
|
1165
1252
|
return this.#localStorage.setItem(name, String(data));
|
|
1166
1253
|
}
|
|
@@ -1173,7 +1260,7 @@ class TinyLocalStorage {
|
|
|
1173
1260
|
*/
|
|
1174
1261
|
getNumber(name) {
|
|
1175
1262
|
if (typeof name !== 'string' || !name.length)
|
|
1176
|
-
throw new
|
|
1263
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1177
1264
|
|
|
1178
1265
|
/** @type {number|string|null} */
|
|
1179
1266
|
let number = this.#localStorage.getItem(name);
|
|
@@ -1192,9 +1279,10 @@ class TinyLocalStorage {
|
|
|
1192
1279
|
* @param {boolean} data - The boolean value to store.
|
|
1193
1280
|
*/
|
|
1194
1281
|
setBool(name, data) {
|
|
1282
|
+
this.#isProtectedDbKey(name);
|
|
1195
1283
|
if (typeof name !== 'string' || !name.length)
|
|
1196
|
-
throw new
|
|
1197
|
-
if (typeof data !== 'boolean') throw new
|
|
1284
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1285
|
+
if (typeof data !== 'boolean') throw new TypeError('Value must be a boolean.');
|
|
1198
1286
|
this.emit('setBool', name, data);
|
|
1199
1287
|
return this.#localStorage.setItem(name, String(data));
|
|
1200
1288
|
}
|
|
@@ -1207,7 +1295,7 @@ class TinyLocalStorage {
|
|
|
1207
1295
|
*/
|
|
1208
1296
|
getBool(name) {
|
|
1209
1297
|
if (typeof name !== 'string' || !name.length)
|
|
1210
|
-
throw new
|
|
1298
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1211
1299
|
|
|
1212
1300
|
const value = this.#localStorage.getItem(name);
|
|
1213
1301
|
if (typeof value === 'boolean') return value;
|
|
@@ -1226,7 +1314,7 @@ class TinyLocalStorage {
|
|
|
1226
1314
|
*/
|
|
1227
1315
|
removeItem(name) {
|
|
1228
1316
|
if (typeof name !== 'string' || !name.length)
|
|
1229
|
-
throw new
|
|
1317
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
1230
1318
|
|
|
1231
1319
|
this.emit('removeItem', name);
|
|
1232
1320
|
return this.#localStorage.removeItem(name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function r(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)&&"[object Object]"===Object.prototype.toString.call(e)}e.d(t,{TinyLocalStorage:()=>l});const n=class{#e=new Map;#t=10;#r=!1;setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#n(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.unshift({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}prependListener(e,t){if("string"!=typeof e)throw new TypeError("prepend(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prepend(event, handler): handler must be a function");this.#n(e,t)}prependListenerOnce(e,t){if("string"!=typeof e)throw new TypeError("prependOnceListener(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prependOnceListener(event, handler): handler must be a function");const r=(...n)=>{this.off(e,r),t(...n)};return this.#n(e,r,{once:!0}),r}#s(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.push({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}on(e,t){if("string"!=typeof e)throw new TypeError("on(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#s(e,t)}once(e,t){if("string"!=typeof e)throw new TypeError("The event name must be a string.");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const r=n=>{this.off(e,r),"function"==typeof t&&t(n)};return this.#s(e,r,{once:!0}),r}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){if("string"!=typeof e)throw new TypeError("off(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");const r=this.#e.get(e);if(!Array.isArray(r))return;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}offAll(e){if("string"!=typeof e)throw new TypeError("The event name must be a string.");this.#e.delete(e)}offAllTypes(){this.#e.clear()}listenerCount(e){if("string"!=typeof e)throw new TypeError("listenerCount(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?t.length:0}listeners(e){if("string"!=typeof e)throw new TypeError("listeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>!e.config.once).map(e=>e.handler):[]}onceListeners(e){if("string"!=typeof e)throw new TypeError("onceListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>e.config.once).map(e=>e.handler):[]}allListeners(e){if("string"!=typeof e)throw new TypeError("allListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].map(e=>e.handler):[]}eventNames(){return[...this.#e.keys()]}emit(e,...t){if("string"!=typeof e)throw new TypeError("emit(event, data): event name must be a string");const r=this.#e.get(e);return!(!Array.isArray(r)||0===r.length||(r.forEach(e=>e.handler(...t)),0))}setMaxListeners(e){if(!Number.isInteger(e)||e<0)throw new TypeError("setMaxListeners(n): n must be a non-negative integer");this.#t=e}getMaxListeners(){return this.#t}},s=new Map,o=new Map,i=new Set(["string","boolean","number","object","array",String,Boolean,Number,Object,Array,BigInt,Symbol]);class a{#o=new n;setThrowOnMaxListeners(e){return this.#o.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#o.getThrowOnMaxListeners()}prependListener(e,t){return this.#o.prependListener(e,t)}prependListenerOnce(e,t){return this.#o.prependListenerOnce(e,t)}appendListener(e,t){return this.#o.appendListener(e,t)}appendListenerOnce(e,t){return this.#o.appendListenerOnce(e,t)}on(e,t){return this.#o.on(e,t)}once(e,t){return this.#o.once(e,t)}off(e,t){return this.#o.off(e,t)}offAll(e){return this.#o.offAll(e)}offAllTypes(){return this.#o.offAllTypes()}listenerCount(e){return this.#o.listenerCount(e)}listeners(e){return this.#o.listeners(e)}onceListeners(e){return this.#o.onceListeners(e)}allListeners(e){return this.#o.allListeners(e)}eventNames(){return this.#o.eventNames()}emit(e,...t){return this.#o.emit(e,...t)}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}static hasJsonType(e){return s.has(e)&&o.has(e)||i.has(e)}static registerJsonType(e,t,r,n=!1){if(i.has(e))throw new Error(`Cannot register type "${e}" because it is frozen.`);s.set(e,t),o.set(e,r),n&&i.add(e)}static deleteJsonType(e){if(i.has(e))throw new Error(`Cannot remove type "${e}" because it is frozen.`);let t=!1;return s.delete(e)&&(t=!0),o.delete(e)&&(t=!0),t}static encodeSpecialJson(e){if(void 0===e)return{__undefined__:!0};if(null===e)return{__null__:!0};for(const[t,r]of s.entries())if("string"!=typeof t&&e instanceof t||typeof e===t)return r(e,a.encodeSpecialJson);if(Array.isArray(e))return e.map(a.encodeSpecialJson);if(r(e)){const t={};for(const r in e)t[r]=a.encodeSpecialJson(e[r]);return t}return e}static decodeSpecialJson(e){const t=r(e);if(t){if(e.__undefined__)return;if(e.__null__)return null}if(Array.isArray(e))return e.map(a.decodeSpecialJson);if(t){for(const[t,r]of o.entries())if(r.check&&r.check(e))return r.decode(e,a.decodeSpecialJson);const t={};for(const r in e)t[r]=a.decodeSpecialJson(e[r]);return t}return e}#i=window.localStorage;#a=e=>this.emit("storage",e);constructor(){window.addEventListener("storage",this.#a)}setLocalStorage(e){if(!(e instanceof Storage))throw new Error("Argument must be a valid instance of Storage.");this.#i=e}localStorageExists(){return this.#i instanceof Storage}#l(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");return a.encodeSpecialJson(t)}setJson(e,t){if(!(r(t)||Array.isArray(t)||t instanceof Map||t instanceof Set))throw new Error("The storage value is not a valid JSON-compatible structure.");const n=this.#l(e,t);return this.emit("setJson",e,t),this.#i.setItem(e,JSON.stringify(n))}#c(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");const r=this.#i.getItem(e),n={obj:()=>({}),array:()=>[],map:()=>new Map,set:()=>new Set},s="function"==typeof n[t]?n[t]():null;let o;try{o=JSON.parse(r)}catch{return s}return{decoded:a.decodeSpecialJson(o),fallback:s}}getJson(e,t){const{decoded:n,fallback:s}=this.#c(e,t);return n instanceof Map||n instanceof Set||Array.isArray(n)||r(n)?n:s}setDate(e,t){if(!(t instanceof Date))throw new Error("Value must be a Date.");const r=this.#l(e,t);return this.emit("setDate",e,t),this.#i.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#c(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(!(t instanceof RegExp))throw new Error("Value must be a RegExp.");const r=this.#l(e,t);return this.emit("setRegExp",e,t),this.#i.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#c(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if("bigint"!=typeof t)throw new Error("Value must be a BigInt.");const r=this.#l(e,t);return this.emit("setBigInt",e,t),this.#i.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#c(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if("symbol"!=typeof t)throw new Error("Value must be a Symbol.");const r=this.#l(e,t);return this.emit("setSymbol",e,t),this.#i.setItem(e,JSON.stringify(r))}getSymbol(e){const t=this.#c(e).decoded;return"symbol"==typeof t?t:null}getValue(e){return this.#c(e).decoded??null}setItem(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#i.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");return this.#i.getItem(e)}setString(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");if("string"!=typeof t)throw new Error("Value must be a string.");return this.emit("setString",e,t),this.#i.setItem(e,JSON.stringify({__string__:!0,value:t}))}getString(e){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");let t=this.#i.getItem(e);try{if(t=JSON.parse(t),!r(t)||!t.__string__||"string"!=typeof t.value)return null;t=t.value}catch{t=null}return"string"==typeof t?t:null}setNumber(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");if("number"!=typeof t)throw new Error("Value must be a number.");return this.emit("setNumber",e,t),this.#i.setItem(e,String(t))}getNumber(e){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");let t=this.#i.getItem(e);return"number"==typeof t||"string"==typeof t&&t.length>0&&(t=parseFloat(t),!Number.isNaN(t))?t:null}setBool(e,t){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");if("boolean"!=typeof t)throw new Error("Value must be a boolean.");return this.emit("setBool",e,t),this.#i.setItem(e,String(t))}getBool(e){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");const t=this.#i.getItem(e);if("boolean"==typeof t)return t;if("string"==typeof t){if("true"===t)return!0;if("false"===t)return!1}return null}removeItem(e){if("string"!=typeof e||!e.length)throw new Error("Key must be a non-empty string.");return this.emit("removeItem",e),this.#i.removeItem(e)}clearLocalStorage(){return this.#i.clear()}destroy(){window.removeEventListener("storage",this.#a),this.#o.offAllTypes()}}a.registerJsonType(Map,(e,t)=>({__map__:!0,data:Array.from(e.entries()).map(([e,r])=>[e,t(r)])}),{check:e=>e.__map__,decode:(e,t)=>new Map(e.data.map(([e,r])=>[e,t(r)]))},!0),a.registerJsonType(Set,(e,t)=>({__set__:!0,data:Array.from(e).map(t)}),{check:e=>e.__set__,decode:(e,t)=>new Set(e.data.map(t))},!0),a.registerJsonType(Date,e=>({__date__:!0,value:e.toISOString()}),{check:e=>e.__date__,decode:e=>new Date(e.value)},!0),a.registerJsonType(RegExp,e=>({__regexp__:!0,source:e.source,flags:e.flags}),{check:e=>e.__regexp__,decode:e=>new RegExp(e.source,e.flags)},!0),a.registerJsonType("bigint",e=>({__bigint__:!0,value:e.toString()}),{check:e=>e.__bigint__,decode:e=>BigInt(e.value)},!0),a.registerJsonType("symbol",e=>({__symbol__:!0,key:Symbol.keyFor(e)??e.description??null}),{check:e=>e.__symbol__,decode:e=>{const t=e.key;return null!=t?Symbol.for(t):Symbol()}},!0);const l=a;window.TinyLocalStorage=t.TinyLocalStorage})();
|
|
1
|
+
(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function r(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)&&"[object Object]"===Object.prototype.toString.call(e)}e.d(t,{TinyLocalStorage:()=>l});const n=class{#e=new Map;#t=10;#r=!1;setThrowOnMaxListeners(e){if("boolean"!=typeof e)throw new TypeError("setThrowOnMaxListeners(value): value must be a boolean");this.#r=e}getThrowOnMaxListeners(){return this.#r}#n(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.unshift({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}prependListener(e,t){if("string"!=typeof e)throw new TypeError("prepend(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prepend(event, handler): handler must be a function");this.#n(e,t)}prependListenerOnce(e,t){if("string"!=typeof e)throw new TypeError("prependOnceListener(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("prependOnceListener(event, handler): handler must be a function");const r=(...n)=>{this.off(e,r),t(...n)};return this.#n(e,r,{once:!0}),r}#s(e,t,{once:r=!1}={}){let n=this.#e.get(e);Array.isArray(n)||(n=[],this.#e.set(e,n)),n.push({handler:t,config:{once:r}});const s=this.#t;if(s>0&&n.length>s){const t=`Possible memory leak detected. ${n.length} "${e}" listeners added. Use setMaxListeners() to increase limit.`;if(this.#r)throw new Error(t);console.warn(t)}}on(e,t){if("string"!=typeof e)throw new TypeError("on(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("on(event, handler): handler must be a function");return this.#s(e,t)}once(e,t){if("string"!=typeof e)throw new TypeError("The event name must be a string.");if("function"!=typeof t)throw new TypeError("once(event, handler): handler must be a function");const r=n=>{this.off(e,r),"function"==typeof t&&t(n)};return this.#s(e,r,{once:!0}),r}appendListener(e,t){return this.on(e,t)}appendListenerOnce(e,t){return this.once(e,t)}off(e,t){if("string"!=typeof e)throw new TypeError("off(event, handler): event name must be a string");if("function"!=typeof t)throw new TypeError("off(event, handler): handler must be a function");const r=this.#e.get(e);if(!Array.isArray(r))return;const n=r.findIndex(e=>e.handler===t);-1!==n&&r.splice(n,1),0===r.length&&this.#e.delete(e)}offAll(e){if("string"!=typeof e)throw new TypeError("The event name must be a string.");this.#e.delete(e)}offAllTypes(){this.#e.clear()}listenerCount(e){if("string"!=typeof e)throw new TypeError("listenerCount(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?t.length:0}listeners(e){if("string"!=typeof e)throw new TypeError("listeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>!e.config.once).map(e=>e.handler):[]}onceListeners(e){if("string"!=typeof e)throw new TypeError("onceListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].filter(e=>e.config.once).map(e=>e.handler):[]}allListeners(e){if("string"!=typeof e)throw new TypeError("allListeners(event): event name must be a string");const t=this.#e.get(e);return Array.isArray(t)?[...t].map(e=>e.handler):[]}eventNames(){return[...this.#e.keys()]}emit(e,...t){if("string"!=typeof e)throw new TypeError("emit(event, data): event name must be a string");const r=this.#e.get(e);return!(!Array.isArray(r)||0===r.length||(r.forEach(e=>e.handler(...t)),0))}setMaxListeners(e){if(!Number.isInteger(e)||e<0)throw new TypeError("setMaxListeners(n): n must be a non-negative integer");this.#t=e}getMaxListeners(){return this.#t}},s=new Map,o=new Map,i=new Set(["string","boolean","number","object","array",String,Boolean,Number,Object,Array,BigInt,Symbol]);class a{#o=new n;setThrowOnMaxListeners(e){return this.#o.setThrowOnMaxListeners(e)}getThrowOnMaxListeners(){return this.#o.getThrowOnMaxListeners()}prependListener(e,t){return this.#o.prependListener(e,t)}prependListenerOnce(e,t){return this.#o.prependListenerOnce(e,t)}appendListener(e,t){return this.#o.appendListener(e,t)}appendListenerOnce(e,t){return this.#o.appendListenerOnce(e,t)}on(e,t){return this.#o.on(e,t)}once(e,t){return this.#o.once(e,t)}off(e,t){return this.#o.off(e,t)}offAll(e){return this.#o.offAll(e)}offAllTypes(){return this.#o.offAllTypes()}listenerCount(e){return this.#o.listenerCount(e)}listeners(e){return this.#o.listeners(e)}onceListeners(e){return this.#o.onceListeners(e)}allListeners(e){return this.#o.allListeners(e)}eventNames(){return this.#o.eventNames()}emit(e,...t){return this.#o.emit(e,...t)}setMaxListeners(e){return this.#o.setMaxListeners(e)}getMaxListeners(){return this.#o.getMaxListeners()}static hasJsonType(e){return s.has(e)&&o.has(e)||i.has(e)}static registerJsonType(e,t,r,n=!1){if(i.has(e))throw new Error(`Cannot register type "${e}" because it is frozen.`);s.set(e,t),o.set(e,r),n&&i.add(e)}static deleteJsonType(e){if(i.has(e))throw new Error(`Cannot remove type "${e}" because it is frozen.`);let t=!1;return s.delete(e)&&(t=!0),o.delete(e)&&(t=!0),t}static encodeSpecialJson(e){if(void 0===e)return{__undefined__:!0};if(null===e)return{__null__:!0};for(const[t,r]of s.entries())if("string"!=typeof t&&e instanceof t||typeof e===t)return r(e,a.encodeSpecialJson);if(Array.isArray(e))return e.map(a.encodeSpecialJson);if(r(e)){const t={};for(const r in e)t[r]=a.encodeSpecialJson(e[r]);return t}return e}static decodeSpecialJson(e){const t=r(e);if(t){if(e.__undefined__)return;if(e.__null__)return null}if(Array.isArray(e))return e.map(a.decodeSpecialJson);if(t){for(const[t,r]of o.entries())if(r.check&&r.check(e))return r.decode(e,a.decodeSpecialJson);const t={};for(const r in e)t[r]=a.decodeSpecialJson(e[r]);return t}return e}#i=window.localStorage;#a=null;#l=0;#c=e=>this.emit("storage",e);constructor(e){if(void 0!==e&&"string"!=typeof e)throw new TypeError("TinyLocalStorage: dbName must be a string if provided.");"string"==typeof e&&(this.#a=`LSDB::${e}`),window.addEventListener("storage",this.#c)}#h(e){if("string"==typeof e&&e.startsWith("LSDB::"))throw new Error(`TinyLocalStorage: Key "${e}" may conflict with reserved dbKeys.`)}updateStorageVersion(e,t){if("string"!=typeof this.#a)throw new Error("TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.");if("number"!=typeof e||Number.isNaN(e)||e<1)throw new TypeError("TinyLocalStorage: version must be a positive number.");if("function"!=typeof t)throw new TypeError("TinyLocalStorage: onUpgrade must be a function.");const r=parseInt(localStorage.getItem(this.#a),10)||0;if("number"!=typeof r||Number.isNaN(r)||r<0)throw new TypeError("TinyLocalStorage: saved version in localStorage is not a valid number.");if(e<r)throw new Error(`TinyLocalStorage: Cannot downgrade database version from ${r} to ${e}.`);e>r&&(t(r,e),localStorage.setItem(this.#a,String(e)),this.#l=e)}getDbKey(){return this.#a}getVersion(){return this.#l}setLocalStorage(e){if(!(e instanceof Storage))throw new TypeError("Argument must be a valid instance of Storage.");this.#i=e}localStorageExists(){return this.#i instanceof Storage}#y(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return a.encodeSpecialJson(t)}setJson(e,t){if(this.#h(e),!(r(t)||Array.isArray(t)||t instanceof Map||t instanceof Set))throw new TypeError("The storage value is not a valid JSON-compatible structure.");const n=this.#y(e,t);return this.emit("setJson",e,t),this.#i.setItem(e,JSON.stringify(n))}#g(e,t){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const r=this.#i.getItem(e),n={obj:()=>({}),array:()=>[],map:()=>new Map,set:()=>new Set},s="function"==typeof n[t]?n[t]():null;let o;try{o=JSON.parse(r)}catch{return s}return{decoded:a.decodeSpecialJson(o),fallback:s}}getJson(e,t){const{decoded:n,fallback:s}=this.#g(e,t);return n instanceof Map||n instanceof Set||Array.isArray(n)||r(n)?n:s}setDate(e,t){if(this.#h(e),!(t instanceof Date))throw new TypeError("Value must be a Date.");const r=this.#y(e,t);return this.emit("setDate",e,t),this.#i.setItem(e,JSON.stringify(r))}getDate(e){const t=this.#g(e).decoded;return t instanceof Date?t:null}setRegExp(e,t){if(this.#h(e),!(t instanceof RegExp))throw new TypeError("Value must be a RegExp.");const r=this.#y(e,t);return this.emit("setRegExp",e,t),this.#i.setItem(e,JSON.stringify(r))}getRegExp(e){const t=this.#g(e).decoded;return t instanceof RegExp?t:null}setBigInt(e,t){if(this.#h(e),"bigint"!=typeof t)throw new TypeError("Value must be a BigInt.");const r=this.#y(e,t);return this.emit("setBigInt",e,t),this.#i.setItem(e,JSON.stringify(r))}getBigInt(e){const t=this.#g(e).decoded;return"bigint"==typeof t?t:null}setSymbol(e,t){if(this.#h(e),"symbol"!=typeof t)throw new TypeError("Value must be a Symbol.");const r=this.#y(e,t);return this.emit("setSymbol",e,t),this.#i.setItem(e,JSON.stringify(r))}getSymbol(e){const t=this.#g(e).decoded;return"symbol"==typeof t?t:null}getValue(e){return this.#g(e).decoded??null}setItem(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("setItem",e,t),this.#i.setItem(e,t)}getItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.#i.getItem(e)}setString(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("string"!=typeof t)throw new TypeError("Value must be a string.");return this.emit("setString",e,t),this.#i.setItem(e,JSON.stringify({__string__:!0,value:t}))}getString(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);try{if(t=JSON.parse(t),!r(t)||!t.__string__||"string"!=typeof t.value)return null;t=t.value}catch{t=null}return"string"==typeof t?t:null}setNumber(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("number"!=typeof t)throw new TypeError("Value must be a number.");return this.emit("setNumber",e,t),this.#i.setItem(e,String(t))}getNumber(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");let t=this.#i.getItem(e);return"number"==typeof t||"string"==typeof t&&t.length>0&&(t=parseFloat(t),!Number.isNaN(t))?t:null}setBool(e,t){if(this.#h(e),"string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");if("boolean"!=typeof t)throw new TypeError("Value must be a boolean.");return this.emit("setBool",e,t),this.#i.setItem(e,String(t))}getBool(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");const t=this.#i.getItem(e);if("boolean"==typeof t)return t;if("string"==typeof t){if("true"===t)return!0;if("false"===t)return!1}return null}removeItem(e){if("string"!=typeof e||!e.length)throw new TypeError("Key must be a non-empty string.");return this.emit("removeItem",e),this.#i.removeItem(e)}clearLocalStorage(){return this.#i.clear()}destroy(){window.removeEventListener("storage",this.#c),this.#o.offAllTypes()}}a.registerJsonType(Map,(e,t)=>({__map__:!0,data:Array.from(e.entries()).map(([e,r])=>[e,t(r)])}),{check:e=>e.__map__,decode:(e,t)=>new Map(e.data.map(([e,r])=>[e,t(r)]))},!0),a.registerJsonType(Set,(e,t)=>({__set__:!0,data:Array.from(e).map(t)}),{check:e=>e.__set__,decode:(e,t)=>new Set(e.data.map(t))},!0),a.registerJsonType(Date,e=>({__date__:!0,value:e.toISOString()}),{check:e=>e.__date__,decode:e=>new Date(e.value)},!0),a.registerJsonType(RegExp,e=>({__regexp__:!0,source:e.source,flags:e.flags}),{check:e=>e.__regexp__,decode:e=>new RegExp(e.source,e.flags)},!0),a.registerJsonType("bigint",e=>({__bigint__:!0,value:e.toString()}),{check:e=>e.__bigint__,decode:e=>BigInt(e.value)},!0),a.registerJsonType("symbol",e=>({__symbol__:!0,key:Symbol.keyFor(e)??e.description??null}),{check:e=>e.__symbol__,decode:e=>{const t=e.key;return null!=t?Symbol.for(t):Symbol()}},!0);const l=a;window.TinyLocalStorage=t.TinyLocalStorage})();
|