@elasticias/utils 1.0.2 → 1.0.4
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.
|
@@ -218,9 +218,69 @@ class NumberUtils {
|
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* A single piece of component state that should survive a page refresh —
|
|
223
|
+
* the active period on a dashboard, a chosen tab, a collapsed rail.
|
|
224
|
+
*
|
|
225
|
+
* Every operation is best-effort. Storage can be unavailable (private
|
|
226
|
+
* browsing, a locked-down browser), the entry can be corrupt, or it can
|
|
227
|
+
* hold a shape from a previous release. In all of those cases `read()`
|
|
228
|
+
* returns `null` and the caller keeps its own default, which is why this
|
|
229
|
+
* is only ever suitable for convenience state and never for anything the
|
|
230
|
+
* app depends on being there.
|
|
231
|
+
*
|
|
232
|
+
* Reach for it through `AbstractComponent.persisted()` inside a screen;
|
|
233
|
+
* construct it directly in components that sit outside that hierarchy.
|
|
234
|
+
*/
|
|
235
|
+
class PersistedState {
|
|
236
|
+
key;
|
|
237
|
+
options;
|
|
238
|
+
constructor(key, options = {}) {
|
|
239
|
+
this.key = key;
|
|
240
|
+
this.options = options;
|
|
241
|
+
}
|
|
242
|
+
/** The stored value, or `null` when there is nothing usable. */
|
|
243
|
+
read() {
|
|
244
|
+
try {
|
|
245
|
+
const raw = this.options.session
|
|
246
|
+
? StorageUtils.getSession(this.key)
|
|
247
|
+
: StorageUtils.getLocal(this.key);
|
|
248
|
+
if (raw === null || raw === undefined)
|
|
249
|
+
return null;
|
|
250
|
+
return this.options.revive ? this.options.revive(raw) : raw;
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
write(value) {
|
|
257
|
+
try {
|
|
258
|
+
const payload = this.options.serialize ? this.options.serialize(value) : value;
|
|
259
|
+
if (this.options.session)
|
|
260
|
+
StorageUtils.setSession(this.key, payload);
|
|
261
|
+
else
|
|
262
|
+
StorageUtils.setLocal(this.key, payload);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
/* Storage is a convenience here, never a contract. */
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
clear() {
|
|
269
|
+
try {
|
|
270
|
+
if (this.options.session)
|
|
271
|
+
StorageUtils.removeSession(this.key);
|
|
272
|
+
else
|
|
273
|
+
StorageUtils.removeLocal(this.key);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
/* ignore */
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
221
281
|
/**
|
|
222
282
|
* Generated bundle index. Do not edit.
|
|
223
283
|
*/
|
|
224
284
|
|
|
225
|
-
export { AppUtils, CsvUtils, NumberUtils, StorageUtils, UuidUtils };
|
|
285
|
+
export { AppUtils, CsvUtils, NumberUtils, PersistedState, StorageUtils, UuidUtils };
|
|
226
286
|
//# sourceMappingURL=elasticias-utils.mjs.map
|
|
@@ -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/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","/**\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 =, +, -, @ 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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"}
|
package/package.json
CHANGED
|
@@ -53,5 +53,47 @@ declare class NumberUtils {
|
|
|
53
53
|
}): string;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Options for {@link PersistedState}.
|
|
58
|
+
*/
|
|
59
|
+
interface PersistedStateOptions<T> {
|
|
60
|
+
/** Keep the value in sessionStorage (dies with the tab) instead of
|
|
61
|
+
* localStorage (survives a browser restart). Default: localStorage. */
|
|
62
|
+
session?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Rebuild `T` from what came back out of JSON. Required whenever the
|
|
65
|
+
* shape holds anything JSON cannot carry — a `Date` round-trips as an
|
|
66
|
+
* ISO string, and code downstream that calls `.getTime()` on it breaks
|
|
67
|
+
* far away from here. Return `null` to reject a value written by an
|
|
68
|
+
* older version of the app.
|
|
69
|
+
*/
|
|
70
|
+
revive?: (raw: unknown) => T | null;
|
|
71
|
+
/** Serialize before writing, when the in-memory shape isn't plain JSON. */
|
|
72
|
+
serialize?: (value: T) => unknown;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A single piece of component state that should survive a page refresh —
|
|
76
|
+
* the active period on a dashboard, a chosen tab, a collapsed rail.
|
|
77
|
+
*
|
|
78
|
+
* Every operation is best-effort. Storage can be unavailable (private
|
|
79
|
+
* browsing, a locked-down browser), the entry can be corrupt, or it can
|
|
80
|
+
* hold a shape from a previous release. In all of those cases `read()`
|
|
81
|
+
* returns `null` and the caller keeps its own default, which is why this
|
|
82
|
+
* is only ever suitable for convenience state and never for anything the
|
|
83
|
+
* app depends on being there.
|
|
84
|
+
*
|
|
85
|
+
* Reach for it through `AbstractComponent.persisted()` inside a screen;
|
|
86
|
+
* construct it directly in components that sit outside that hierarchy.
|
|
87
|
+
*/
|
|
88
|
+
declare class PersistedState<T> {
|
|
89
|
+
private readonly key;
|
|
90
|
+
private readonly options;
|
|
91
|
+
constructor(key: string, options?: PersistedStateOptions<T>);
|
|
92
|
+
/** The stored value, or `null` when there is nothing usable. */
|
|
93
|
+
read(): T | null;
|
|
94
|
+
write(value: T): void;
|
|
95
|
+
clear(): void;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { AppUtils, CsvUtils, NumberUtils, PersistedState, StorageUtils, UuidUtils };
|
|
99
|
+
export type { CsvColumn, PersistedStateOptions };
|