@elasticias/utils 1.0.47 → 1.0.49
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.
|
@@ -140,11 +140,11 @@ class UuidUtils {
|
|
|
140
140
|
class CsvUtils {
|
|
141
141
|
/** fr-MA Excel convention: ';' separator. Output has a header row, CRLF endings. */
|
|
142
142
|
static toCsv(rows, columns, separator = ';') {
|
|
143
|
-
// Excel/LibreOffice treat cells starting with =, +, -,
|
|
143
|
+
// Excel/LibreOffice treat cells starting with =, +, -, @, a tab or a CR as formulas.
|
|
144
144
|
// Operator-entered client/product names could carry these as their first
|
|
145
145
|
// character, so string values are neutralized (numbers are never affected —
|
|
146
146
|
// the guard only applies before coercion, when `raw` is actually a string).
|
|
147
|
-
const needsFormulaGuard = (value) => /^[=+\-@\t]/.test(value);
|
|
147
|
+
const needsFormulaGuard = (value) => /^[=+\-@\t\r]/.test(value);
|
|
148
148
|
const escape = (raw) => {
|
|
149
149
|
if (raw === null || raw === undefined)
|
|
150
150
|
return '';
|
|
@@ -153,7 +153,7 @@ class CsvUtils {
|
|
|
153
153
|
const guard = isString && needsFormulaGuard(s);
|
|
154
154
|
if (guard)
|
|
155
155
|
s = `'${s}`;
|
|
156
|
-
return guard || s.includes(separator) || s.includes('"') || s.includes('\n')
|
|
156
|
+
return guard || s.includes(separator) || s.includes('"') || s.includes('\n') || s.includes('\r')
|
|
157
157
|
? `"${s.replace(/"/g, '""')}"`
|
|
158
158
|
: s;
|
|
159
159
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elasticias-utils.mjs","sources":["../../../../libs/utils/src/lib/storage.utils.ts","../../../../libs/utils/src/lib/app.utils.ts","../../../../libs/utils/src/lib/uuid.utils.ts","../../../../libs/utils/src/lib/csv.utils.ts","../../../../libs/utils/src/lib/number.utils.ts","../../../../libs/utils/src/lib/persisted-state.ts","../../../../libs/utils/src/elasticias-utils.ts"],"sourcesContent":["/**\n * Configurable prefix-based wrapper for localStorage and sessionStorage.\n * Default prefix is 'Elasticias_'. Override via `StorageUtils.configure()`.\n */\nexport class StorageUtils {\n private static _prefix = 'Elasticias_';\n\n static configure(prefix: string): void {\n StorageUtils._prefix = prefix;\n }\n\n static get prefix(): string {\n return StorageUtils._prefix;\n }\n\n private static getPrefixedKey(key: string): string {\n return `${StorageUtils._prefix}${key}`;\n }\n\n static setLocal(key: string, value: unknown): void {\n try {\n const localKey = this.getPrefixedKey(key);\n localStorage.setItem(localKey, JSON.stringify(value));\n } catch (error) {\n console.error('Error storing data in localStorage: ', key, error);\n }\n }\n\n static getLocal<T>(key: string, usePrefix = true): T | null {\n const localKey = usePrefix ? this.getPrefixedKey(key) : key;\n const item = localStorage.getItem(localKey);\n try {\n if (item) {\n return JSON.parse(item) as T;\n }\n } catch (error) {\n console.error('Error parsing JSON from localStorage: ', key, error);\n }\n return null;\n }\n\n static removeLocal(key: string): void {\n localStorage.removeItem(this.getPrefixedKey(key));\n }\n\n static clearLocal(): void {\n localStorage.clear();\n }\n\n static setSession(key: string, value: unknown): void {\n const sessionKey = this.getPrefixedKey(key);\n sessionStorage.setItem(sessionKey, JSON.stringify(value));\n }\n\n static getSession<T>(key: string): T | null {\n const sessionKey = this.getPrefixedKey(key);\n const item = sessionStorage.getItem(sessionKey);\n return item ? (JSON.parse(item) as T) : null;\n }\n\n static removeSession(key: string): void {\n sessionStorage.removeItem(this.getPrefixedKey(key));\n }\n\n static clearSession(): void {\n sessionStorage.clear();\n }\n\n static existsLocal(key: string): boolean {\n return localStorage.getItem(this.getPrefixedKey(key)) !== null;\n }\n\n static existsSession(key: string): boolean {\n return sessionStorage.getItem(this.getPrefixedKey(key)) !== null;\n }\n}\n","export class AppUtils {\n static toCamelCase(str: string): string {\n if (!str) return '';\n const words = str\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .split(/[\\s_]+/)\n .filter(Boolean);\n\n return words\n .map((word, index) => {\n word = word.toLowerCase();\n return index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1);\n })\n .join('');\n }\n\n static toPascalCase(str: string): string {\n const words = str.split(/[\\s_]+/).filter(Boolean);\n return words\n .map((word) => {\n word = word.toLowerCase();\n return word.charAt(0).toUpperCase() + word.slice(1);\n })\n .join('');\n }\n\n static toSnakeCase(str: string): string {\n const words = str.split(/[\\s_]+/).filter(Boolean);\n return words.map((word) => word.toLowerCase()).join('_');\n }\n\n static isNullOrEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && Object.keys(value).length === 0) return true;\n return false;\n }\n\n static truncate(\n text: string | null | undefined,\n maxLength = 50,\n ellipsis = '...',\n preserveWords = false\n ): string {\n if (!text) return '';\n if (text.length <= maxLength) return text;\n\n if (maxLength < ellipsis.length + 2) {\n return text.slice(0, Math.max(0, maxLength - ellipsis.length)) + ellipsis;\n }\n\n const visibleChars = maxLength - ellipsis.length;\n const startChars = Math.ceil(visibleChars / 2);\n const endChars = Math.floor(visibleChars / 2);\n\n let start = text.slice(0, startChars);\n let end = text.slice(text.length - endChars);\n\n if (preserveWords) {\n const lastSpaceInStart = start.lastIndexOf(' ');\n if (lastSpaceInStart > visibleChars * 0.3) {\n start = start.slice(0, lastSpaceInStart);\n }\n const firstSpaceInEnd = end.indexOf(' ');\n if (firstSpaceInEnd !== -1 && firstSpaceInEnd < endChars * 0.7) {\n end = end.slice(firstSpaceInEnd + 1);\n }\n }\n\n return `${start}${ellipsis}${end}`;\n }\n}\n","export class UuidUtils {\n static randomUUID(): string {\n if (globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n","export interface CsvColumn<T> {\n key: keyof T & string;\n header: string;\n}\n\nexport class CsvUtils {\n /** fr-MA Excel convention: ';' separator. Output has a header row, CRLF endings. */\n static toCsv<T>(\n rows: ReadonlyArray<T>,\n columns: ReadonlyArray<CsvColumn<T>>,\n separator = ';',\n ): string {\n // Excel/LibreOffice treat cells starting with =, +, -, @ or a tab as formulas.\n // Operator-entered client/product names could carry these as their first\n // character, so string values are neutralized (numbers are never affected —\n // the guard only applies before coercion, when `raw` is actually a string).\n const needsFormulaGuard = (value: string): boolean => /^[=+\\-@\\t]/.test(value);\n const escape = (raw: unknown): string => {\n if (raw === null || raw === undefined) return '';\n const isString = typeof raw === 'string';\n let s = String(raw);\n const guard = isString && needsFormulaGuard(s);\n if (guard) s = `'${s}`;\n return guard || s.includes(separator) || s.includes('\"') || s.includes('\\n')\n ? `\"${s.replace(/\"/g, '\"\"')}\"`\n : s;\n };\n const header = columns.map((c) => escape(c.header)).join(separator);\n const lines = rows.map((r) => columns.map((c) => escape(r[c.key])).join(separator));\n return [header, ...lines].join('\\r\\n');\n }\n\n /** UTF-8 BOM so Excel opens French accents / Arabic correctly. */\n static download(filename: string, csv: string): void {\n const blob = new Blob(['', csv], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n }\n}\n","interface CompactUnit {\n readonly threshold: number;\n readonly divisor: number;\n readonly suffix: string;\n}\n\n// Ordered largest-first so the first matching threshold wins.\nconst UNITS: readonly CompactUnit[] = [\n { threshold: 1_000_000_000, divisor: 1_000_000_000, suffix: 'Md' },\n { threshold: 1_000_000, divisor: 1_000_000, suffix: 'M' },\n { threshold: 1_000, divisor: 1_000, suffix: 'k' },\n];\n\nexport class NumberUtils {\n /**\n * Compact human-readable number: 1000 → \"1 k\", 2_500_000 → \"2,5 M\" (fr decimal comma).\n * maxDecimals applies after scaling; trailing zeros stripped. Below 1000 → localized plain number.\n */\n static compact(value: number, opts?: { locale?: string; maxDecimals?: number }): string {\n if (!Number.isFinite(value)) return '';\n\n const locale = opts?.locale ?? 'fr-MA';\n const maxDecimals = opts?.maxDecimals ?? 2;\n\n if (value === 0) return '0';\n\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n\n const format = (n: number, decimals: number): string =>\n n.toLocaleString(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: decimals,\n });\n\n let unit = UNITS.find((u) => abs >= u.threshold);\n if (!unit) {\n return sign + format(abs, maxDecimals);\n }\n\n let scaled = abs / unit.divisor;\n // Rounding at maxDecimals can push the scaled value up to (or past) the\n // next unit's threshold (e.g. 999_999.9 @ 1 decimal -> 1000.0 k). Re-scale\n // in that case so the boundary bumps to the next unit instead.\n const rounded = Number(scaled.toFixed(maxDecimals));\n if (rounded >= 1000) {\n const nextUnitIndex = UNITS.indexOf(unit) - 1;\n const nextUnit = nextUnitIndex >= 0 ? UNITS[nextUnitIndex] : undefined;\n if (nextUnit) {\n unit = nextUnit;\n scaled = abs / unit.divisor;\n }\n }\n\n return `${sign}${format(scaled, maxDecimals)}\\u00A0${unit.suffix}`;\n }\n}\n","import { StorageUtils } from './storage.utils';\n\n/**\n * Options for {@link PersistedState}.\n */\nexport interface PersistedStateOptions<T> {\n /** Keep the value in sessionStorage (dies with the tab) instead of\n * localStorage (survives a browser restart). Default: localStorage. */\n session?: boolean;\n\n /**\n * Rebuild `T` from what came back out of JSON. Required whenever the\n * shape holds anything JSON cannot carry — a `Date` round-trips as an\n * ISO string, and code downstream that calls `.getTime()` on it breaks\n * far away from here. Return `null` to reject a value written by an\n * older version of the app.\n */\n revive?: (raw: unknown) => T | null;\n\n /** Serialize before writing, when the in-memory shape isn't plain JSON. */\n serialize?: (value: T) => unknown;\n}\n\n/**\n * A single piece of component state that should survive a page refresh —\n * the active period on a dashboard, a chosen tab, a collapsed rail.\n *\n * Every operation is best-effort. Storage can be unavailable (private\n * browsing, a locked-down browser), the entry can be corrupt, or it can\n * hold a shape from a previous release. In all of those cases `read()`\n * returns `null` and the caller keeps its own default, which is why this\n * is only ever suitable for convenience state and never for anything the\n * app depends on being there.\n *\n * Reach for it through `AbstractComponent.persisted()` inside a screen;\n * construct it directly in components that sit outside that hierarchy.\n */\nexport class PersistedState<T> {\n constructor(\n private readonly key: string,\n private readonly options: PersistedStateOptions<T> = {},\n ) {}\n\n /** The stored value, or `null` when there is nothing usable. */\n read(): T | null {\n try {\n const raw = this.options.session\n ? StorageUtils.getSession<unknown>(this.key)\n : StorageUtils.getLocal<unknown>(this.key);\n if (raw === null || raw === undefined) return null;\n return this.options.revive ? this.options.revive(raw) : (raw as T);\n } catch {\n return null;\n }\n }\n\n write(value: T): void {\n try {\n const payload = this.options.serialize ? this.options.serialize(value) : value;\n if (this.options.session) StorageUtils.setSession(this.key, payload);\n else StorageUtils.setLocal(this.key, payload);\n } catch {\n /* Storage is a convenience here, never a contract. */\n }\n }\n\n clear(): void {\n try {\n if (this.options.session) StorageUtils.removeSession(this.key);\n else StorageUtils.removeLocal(this.key);\n } catch {\n /* ignore */\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"elasticias-utils.mjs","sources":["../../../../libs/utils/src/lib/storage.utils.ts","../../../../libs/utils/src/lib/app.utils.ts","../../../../libs/utils/src/lib/uuid.utils.ts","../../../../libs/utils/src/lib/csv.utils.ts","../../../../libs/utils/src/lib/number.utils.ts","../../../../libs/utils/src/lib/persisted-state.ts","../../../../libs/utils/src/elasticias-utils.ts"],"sourcesContent":["/**\n * Configurable prefix-based wrapper for localStorage and sessionStorage.\n * Default prefix is 'Elasticias_'. Override via `StorageUtils.configure()`.\n */\nexport class StorageUtils {\n private static _prefix = 'Elasticias_';\n\n static configure(prefix: string): void {\n StorageUtils._prefix = prefix;\n }\n\n static get prefix(): string {\n return StorageUtils._prefix;\n }\n\n private static getPrefixedKey(key: string): string {\n return `${StorageUtils._prefix}${key}`;\n }\n\n static setLocal(key: string, value: unknown): void {\n try {\n const localKey = this.getPrefixedKey(key);\n localStorage.setItem(localKey, JSON.stringify(value));\n } catch (error) {\n console.error('Error storing data in localStorage: ', key, error);\n }\n }\n\n static getLocal<T>(key: string, usePrefix = true): T | null {\n const localKey = usePrefix ? this.getPrefixedKey(key) : key;\n const item = localStorage.getItem(localKey);\n try {\n if (item) {\n return JSON.parse(item) as T;\n }\n } catch (error) {\n console.error('Error parsing JSON from localStorage: ', key, error);\n }\n return null;\n }\n\n static removeLocal(key: string): void {\n localStorage.removeItem(this.getPrefixedKey(key));\n }\n\n static clearLocal(): void {\n localStorage.clear();\n }\n\n static setSession(key: string, value: unknown): void {\n const sessionKey = this.getPrefixedKey(key);\n sessionStorage.setItem(sessionKey, JSON.stringify(value));\n }\n\n static getSession<T>(key: string): T | null {\n const sessionKey = this.getPrefixedKey(key);\n const item = sessionStorage.getItem(sessionKey);\n return item ? (JSON.parse(item) as T) : null;\n }\n\n static removeSession(key: string): void {\n sessionStorage.removeItem(this.getPrefixedKey(key));\n }\n\n static clearSession(): void {\n sessionStorage.clear();\n }\n\n static existsLocal(key: string): boolean {\n return localStorage.getItem(this.getPrefixedKey(key)) !== null;\n }\n\n static existsSession(key: string): boolean {\n return sessionStorage.getItem(this.getPrefixedKey(key)) !== null;\n }\n}\n","export class AppUtils {\n static toCamelCase(str: string): string {\n if (!str) return '';\n const words = str\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .split(/[\\s_]+/)\n .filter(Boolean);\n\n return words\n .map((word, index) => {\n word = word.toLowerCase();\n return index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1);\n })\n .join('');\n }\n\n static toPascalCase(str: string): string {\n const words = str.split(/[\\s_]+/).filter(Boolean);\n return words\n .map((word) => {\n word = word.toLowerCase();\n return word.charAt(0).toUpperCase() + word.slice(1);\n })\n .join('');\n }\n\n static toSnakeCase(str: string): string {\n const words = str.split(/[\\s_]+/).filter(Boolean);\n return words.map((word) => word.toLowerCase()).join('_');\n }\n\n static isNullOrEmpty(value: unknown): boolean {\n if (value == null) return true;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && Object.keys(value).length === 0) return true;\n return false;\n }\n\n static truncate(\n text: string | null | undefined,\n maxLength = 50,\n ellipsis = '...',\n preserveWords = false\n ): string {\n if (!text) return '';\n if (text.length <= maxLength) return text;\n\n if (maxLength < ellipsis.length + 2) {\n return text.slice(0, Math.max(0, maxLength - ellipsis.length)) + ellipsis;\n }\n\n const visibleChars = maxLength - ellipsis.length;\n const startChars = Math.ceil(visibleChars / 2);\n const endChars = Math.floor(visibleChars / 2);\n\n let start = text.slice(0, startChars);\n let end = text.slice(text.length - endChars);\n\n if (preserveWords) {\n const lastSpaceInStart = start.lastIndexOf(' ');\n if (lastSpaceInStart > visibleChars * 0.3) {\n start = start.slice(0, lastSpaceInStart);\n }\n const firstSpaceInEnd = end.indexOf(' ');\n if (firstSpaceInEnd !== -1 && firstSpaceInEnd < endChars * 0.7) {\n end = end.slice(firstSpaceInEnd + 1);\n }\n }\n\n return `${start}${ellipsis}${end}`;\n }\n}\n","export class UuidUtils {\n static randomUUID(): string {\n if (globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n }\n}\n","export interface CsvColumn<T> {\n key: keyof T & string;\n header: string;\n}\n\nexport class CsvUtils {\n /** fr-MA Excel convention: ';' separator. Output has a header row, CRLF endings. */\n static toCsv<T>(\n rows: ReadonlyArray<T>,\n columns: ReadonlyArray<CsvColumn<T>>,\n separator = ';',\n ): string {\n // Excel/LibreOffice treat cells starting with =, +, -, @, a tab or a CR as formulas.\n // Operator-entered client/product names could carry these as their first\n // character, so string values are neutralized (numbers are never affected —\n // the guard only applies before coercion, when `raw` is actually a string).\n const needsFormulaGuard = (value: string): boolean => /^[=+\\-@\\t\\r]/.test(value);\n const escape = (raw: unknown): string => {\n if (raw === null || raw === undefined) return '';\n const isString = typeof raw === 'string';\n let s = String(raw);\n const guard = isString && needsFormulaGuard(s);\n if (guard) s = `'${s}`;\n return guard || s.includes(separator) || s.includes('\"') || s.includes('\\n') || s.includes('\\r')\n ? `\"${s.replace(/\"/g, '\"\"')}\"`\n : s;\n };\n const header = columns.map((c) => escape(c.header)).join(separator);\n const lines = rows.map((r) => columns.map((c) => escape(r[c.key])).join(separator));\n return [header, ...lines].join('\\r\\n');\n }\n\n /** UTF-8 BOM so Excel opens French accents / Arabic correctly. */\n static download(filename: string, csv: string): void {\n const blob = new Blob(['', csv], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n }\n}\n","interface CompactUnit {\n readonly threshold: number;\n readonly divisor: number;\n readonly suffix: string;\n}\n\n// Ordered largest-first so the first matching threshold wins.\nconst UNITS: readonly CompactUnit[] = [\n { threshold: 1_000_000_000, divisor: 1_000_000_000, suffix: 'Md' },\n { threshold: 1_000_000, divisor: 1_000_000, suffix: 'M' },\n { threshold: 1_000, divisor: 1_000, suffix: 'k' },\n];\n\nexport class NumberUtils {\n /**\n * Compact human-readable number: 1000 → \"1 k\", 2_500_000 → \"2,5 M\" (fr decimal comma).\n * maxDecimals applies after scaling; trailing zeros stripped. Below 1000 → localized plain number.\n */\n static compact(value: number, opts?: { locale?: string; maxDecimals?: number }): string {\n if (!Number.isFinite(value)) return '';\n\n const locale = opts?.locale ?? 'fr-MA';\n const maxDecimals = opts?.maxDecimals ?? 2;\n\n if (value === 0) return '0';\n\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n\n const format = (n: number, decimals: number): string =>\n n.toLocaleString(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: decimals,\n });\n\n let unit = UNITS.find((u) => abs >= u.threshold);\n if (!unit) {\n return sign + format(abs, maxDecimals);\n }\n\n let scaled = abs / unit.divisor;\n // Rounding at maxDecimals can push the scaled value up to (or past) the\n // next unit's threshold (e.g. 999_999.9 @ 1 decimal -> 1000.0 k). Re-scale\n // in that case so the boundary bumps to the next unit instead.\n const rounded = Number(scaled.toFixed(maxDecimals));\n if (rounded >= 1000) {\n const nextUnitIndex = UNITS.indexOf(unit) - 1;\n const nextUnit = nextUnitIndex >= 0 ? UNITS[nextUnitIndex] : undefined;\n if (nextUnit) {\n unit = nextUnit;\n scaled = abs / unit.divisor;\n }\n }\n\n return `${sign}${format(scaled, maxDecimals)}\\u00A0${unit.suffix}`;\n }\n}\n","import { StorageUtils } from './storage.utils';\n\n/**\n * Options for {@link PersistedState}.\n */\nexport interface PersistedStateOptions<T> {\n /** Keep the value in sessionStorage (dies with the tab) instead of\n * localStorage (survives a browser restart). Default: localStorage. */\n session?: boolean;\n\n /**\n * Rebuild `T` from what came back out of JSON. Required whenever the\n * shape holds anything JSON cannot carry — a `Date` round-trips as an\n * ISO string, and code downstream that calls `.getTime()` on it breaks\n * far away from here. Return `null` to reject a value written by an\n * older version of the app.\n */\n revive?: (raw: unknown) => T | null;\n\n /** Serialize before writing, when the in-memory shape isn't plain JSON. */\n serialize?: (value: T) => unknown;\n}\n\n/**\n * A single piece of component state that should survive a page refresh —\n * the active period on a dashboard, a chosen tab, a collapsed rail.\n *\n * Every operation is best-effort. Storage can be unavailable (private\n * browsing, a locked-down browser), the entry can be corrupt, or it can\n * hold a shape from a previous release. In all of those cases `read()`\n * returns `null` and the caller keeps its own default, which is why this\n * is only ever suitable for convenience state and never for anything the\n * app depends on being there.\n *\n * Reach for it through `AbstractComponent.persisted()` inside a screen;\n * construct it directly in components that sit outside that hierarchy.\n */\nexport class PersistedState<T> {\n constructor(\n private readonly key: string,\n private readonly options: PersistedStateOptions<T> = {},\n ) {}\n\n /** The stored value, or `null` when there is nothing usable. */\n read(): T | null {\n try {\n const raw = this.options.session\n ? StorageUtils.getSession<unknown>(this.key)\n : StorageUtils.getLocal<unknown>(this.key);\n if (raw === null || raw === undefined) return null;\n return this.options.revive ? this.options.revive(raw) : (raw as T);\n } catch {\n return null;\n }\n }\n\n write(value: T): void {\n try {\n const payload = this.options.serialize ? this.options.serialize(value) : value;\n if (this.options.session) StorageUtils.setSession(this.key, payload);\n else StorageUtils.setLocal(this.key, payload);\n } catch {\n /* Storage is a convenience here, never a contract. */\n }\n }\n\n clear(): void {\n try {\n if (this.options.session) StorageUtils.removeSession(this.key);\n else StorageUtils.removeLocal(this.key);\n } catch {\n /* ignore */\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|