@shival99/z-ui 1.4.7 → 1.4.9

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.
@@ -1,5 +1,5 @@
1
- import { InjectionToken, makeEnvironmentProviders, inject, provideAppInitializer } from '@angular/core';
2
- import { ZIndexDbService, ZCacheService, Z_THEME_CONFIG, Z_LANG_CACHE_KEY } from '@shival99/z-ui/services';
1
+ import { InjectionToken, makeEnvironmentProviders, provideEnvironmentInitializer, inject, provideAppInitializer } from '@angular/core';
2
+ import { ZCacheService, ZIndexDbService, Z_THEME_CONFIG, Z_LANG_CACHE_KEY } from '@shival99/z-ui/services';
3
3
  import { provideEnvironmentNgxMask } from 'ngx-mask';
4
4
  import { provideScrollbarOptions } from 'ngx-scrollbar';
5
5
  import { HttpClient } from '@angular/common/http';
@@ -8,6 +8,38 @@ import { Z_UI_TRANSLATIONS } from '@shival99/z-ui/i18n';
8
8
  import { of, forkJoin, map, firstValueFrom } from 'rxjs';
9
9
  import { catchError } from 'rxjs/operators';
10
10
 
11
+ /** Injection token for ZCacheService configuration */
12
+ const Z_CACHE_CONFIG = new InjectionToken('Z_CACHE_CONFIG');
13
+ /**
14
+ * Provide Z-Cache service with configuration
15
+ * @param config - Cache configuration with prefix and encrypt options
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // In app.config.ts
20
+ * export const appConfig: ApplicationConfig = {
21
+ * providers: [
22
+ * provideZCache({
23
+ * prefix: 'myapp_',
24
+ * encrypt: false, // Disable encryption for debugging
25
+ * }),
26
+ * ],
27
+ * };
28
+ * ```
29
+ */
30
+ function provideZCache(config = {}) {
31
+ return makeEnvironmentProviders([
32
+ {
33
+ provide: Z_CACHE_CONFIG,
34
+ useValue: config,
35
+ },
36
+ provideEnvironmentInitializer(() => {
37
+ const cacheConfig = inject(Z_CACHE_CONFIG);
38
+ ZCacheService.configure(cacheConfig);
39
+ }),
40
+ ]);
41
+ }
42
+
11
43
  /** Injection token for ZIndexDbService */
12
44
  const Z_INDEXDB_SERVICE = new InjectionToken('ZIndexDbService');
13
45
  /**
@@ -183,5 +215,5 @@ function provideZTranslate(config = {}) {
183
215
  * Generated bundle index. Do not edit.
184
216
  */
185
217
 
186
- export { Z_INDEXDB_SERVICE, provideZIndexDb, provideZNgxMask, provideZScrollbar, provideZTheme, provideZTranslate, zCreateTranslateLoader };
218
+ export { Z_CACHE_CONFIG, Z_INDEXDB_SERVICE, provideZCache, provideZIndexDb, provideZNgxMask, provideZScrollbar, provideZTheme, provideZTranslate, zCreateTranslateLoader };
187
219
  //# sourceMappingURL=shival99-z-ui-providers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shival99-z-ui-providers.mjs","sources":["../../../../libs/core-ui/providers/z-indexdb.provider.ts","../../../../libs/core-ui/providers/z-ngx-mask.provider.ts","../../../../libs/core-ui/providers/z-scrollbar.provider.ts","../../../../libs/core-ui/providers/z-theme.provider.ts","../../../../libs/core-ui/providers/z-translate.provider.ts","../../../../libs/core-ui/providers/types/z-ngx-mask.types.ts","../../../../libs/core-ui/providers/shival99-z-ui-providers.ts"],"sourcesContent":["import { type EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { type ZIndexDbConfig, ZIndexDbService } from '@shival99/z-ui/services';\n\n/** Injection token for ZIndexDbService */\nexport const Z_INDEXDB_SERVICE = new InjectionToken<ZIndexDbService>('ZIndexDbService');\n\n/**\n * Provide Z-IndexDB service with configuration\n * @param config - IndexDB configuration with multi-store support\n *\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZIndexDb({\n * dbName: 'MyApp',\n * version: 1,\n * stores: [\n * { name: 'cache', encrypt: true },\n * { name: 'userData', encrypt: true, protectedKeys: ['profile'] },\n * { name: 'settings', encrypt: false },\n * ],\n * defaultStore: 'cache',\n * protectedKeys: ['token'],\n * }),\n * ],\n * };\n * ```\n */\nexport function provideZIndexDb(config: ZIndexDbConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: Z_INDEXDB_SERVICE,\n useFactory: () => new ZIndexDbService(config),\n },\n {\n provide: ZIndexDbService,\n useExisting: Z_INDEXDB_SERVICE,\n },\n ]);\n}\n","import { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { ZCacheService } from '@shival99/z-ui/services';\nimport { provideEnvironmentNgxMask } from 'ngx-mask';\nimport type { ZNgxMaskConfig } from './types/z-ngx-mask.types';\n\nconst LANG_CACHE_KEY = 'Z_LANGUAGE';\n\n/**\n * Get locale-specific mask configuration\n */\nfunction getMaskConfig(lang: string, config: ZNgxMaskConfig = {}) {\n const isVietnamese = lang === 'vi';\n\n return {\n validation: config.validation ?? true,\n thousandSeparator: isVietnamese ? ',' : '.',\n decimalMarker: (isVietnamese ? '.' : ',') as '.' | ',',\n allowNegativeNumbers: config.allowNegativeNumbers ?? true,\n };\n}\n\n/**\n * Provide Z-NgxMask with locale-aware configuration\n * @param config - Mask configuration\n *\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZNgxMask({ lang: 'vi' }),\n * ],\n * };\n * ```\n */\nexport function provideZNgxMask(config: ZNgxMaskConfig = {}): EnvironmentProviders {\n const savedLang = typeof window !== 'undefined' ? ZCacheService.get<string>(LANG_CACHE_KEY) : null;\n const lang = config.lang ?? savedLang ?? 'vi';\n const maskConfig = getMaskConfig(lang, config);\n\n return makeEnvironmentProviders([provideEnvironmentNgxMask(maskConfig)]);\n}\n","import { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { provideScrollbarOptions } from 'ngx-scrollbar';\n\n/**\n * Provides global scrollbar options for ngx-scrollbar\n * Use this in app.config.ts: providers: [provideZScrollbar()]\n */\nexport function provideZScrollbar(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideScrollbarOptions({\n visibility: 'hover',\n appearance: 'compact',\n withButtons: false,\n sensorThrottleTime: 200,\n }),\n ]);\n}\n","import { makeEnvironmentProviders, type EnvironmentProviders } from '@angular/core';\nimport { type ZThemeConfig, Z_THEME_CONFIG } from '@shival99/z-ui/services';\n\n/**\n * Provide theme configuration for the application\n * @param config - Theme configuration with defaultTheme and defaultDarkMode\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZTheme({ defaultTheme: 'hospital', defaultDarkMode: false })\n * ]\n * };\n * ```\n */\nexport function provideZTheme(config: ZThemeConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: Z_THEME_CONFIG, useValue: config }]);\n}\n","/* eslint-disable @stylistic/indent */\nimport { HttpClient } from '@angular/common/http';\nimport { inject, makeEnvironmentProviders, provideAppInitializer, type EnvironmentProviders } from '@angular/core';\nimport {\n provideTranslateService,\n TranslateLoader,\n TranslateService,\n type TranslationObject,\n} from '@ngx-translate/core';\nimport { Z_UI_TRANSLATIONS, type ZUITranslations } from '@shival99/z-ui/i18n';\nimport { Z_LANG_CACHE_KEY, ZCacheService } from '@shival99/z-ui/services';\nimport { firstValueFrom, forkJoin, map, type Observable, of } from 'rxjs';\nimport { catchError } from 'rxjs/operators';\nimport type { ZTranslateProviderConfig } from './types/z-translate.types';\n\nclass ZTranslateHttpLoader implements TranslateLoader {\n public constructor(\n private readonly _http: HttpClient,\n private readonly _prefix: string,\n private readonly _suffix: string,\n private readonly _includeZUI: boolean,\n private readonly _zuiOverridePath?: string,\n private readonly _customZUI?: Partial<Record<string, ZUITranslations>>\n ) {}\n\n public getTranslation(lang: string): Observable<TranslationObject> {\n const userTranslations$ = this._http\n .get<TranslationObject>(`${this._prefix}${lang}${this._suffix}`)\n .pipe(catchError(() => of({} as TranslationObject)));\n\n if (!this._includeZUI) {\n return userTranslations$;\n }\n\n const zuiDefaults = Z_UI_TRANSLATIONS[lang] ?? Z_UI_TRANSLATIONS['en'] ?? {};\n const zuiFileOverrides$ = this._zuiOverridePath\n ? this._http\n .get<ZUITranslations>(`${this._zuiOverridePath}${lang}${this._suffix}`)\n .pipe(catchError(() => of({} as ZUITranslations)))\n : of({} as ZUITranslations);\n\n const inlineOverrides = this._customZUI?.[lang] ?? {};\n\n return forkJoin([of(zuiDefaults), zuiFileOverrides$, userTranslations$]).pipe(\n map(\n ([defaults, fileOverrides, user]) =>\n ({\n ...defaults,\n ...fileOverrides,\n ...inlineOverrides,\n ...(user as Record<string, unknown>),\n }) as TranslationObject\n )\n );\n }\n}\n\nexport function zCreateTranslateLoader(\n http: HttpClient,\n path = './assets/i18n/',\n extension = '.json',\n includeZUI = true,\n zuiOverridePath?: string,\n customZUI?: Partial<Record<string, ZUITranslations>>\n): TranslateLoader {\n return new ZTranslateHttpLoader(http, path, extension, includeZUI, zuiOverridePath, customZUI);\n}\n\nfunction initializeTranslate(defaultLang: string): Promise<unknown> {\n const translate = inject(TranslateService);\n const savedLang = ZCacheService.get<string>(Z_LANG_CACHE_KEY) ?? defaultLang;\n translate.setFallbackLang(defaultLang);\n return firstValueFrom(translate.use(savedLang));\n}\n\nexport function provideZTranslate(config: ZTranslateProviderConfig = {}): EnvironmentProviders {\n const {\n defaultLang = 'vi',\n translationPath = './assets/i18n/',\n fileExtension = '.json',\n includeZUITranslations = true,\n zuiOverridePath,\n customZUITranslations,\n } = config;\n\n return makeEnvironmentProviders([\n provideTranslateService({\n fallbackLang: defaultLang,\n loader: {\n provide: TranslateLoader,\n useFactory: (http: HttpClient) =>\n zCreateTranslateLoader(\n http,\n translationPath,\n fileExtension,\n includeZUITranslations,\n zuiOverridePath,\n customZUITranslations\n ),\n deps: [HttpClient],\n },\n }),\n provideAppInitializer(() => initializeTranslate(defaultLang)),\n ]);\n}\n\nexport { Z_UI_TRANSLATIONS, mergeTranslations, getZUITranslations } from '@shival99/z-ui/i18n';\nexport type { ZUITranslations, ZUILanguage, ZUITranslationSet } from '@shival99/z-ui/i18n';\n","/**\n * Z-NgxMask Provider Types\n */\n\nexport interface ZNgxMaskConfig {\n /** Language code (vi, en, etc.) */\n lang?: string;\n /** Allow negative numbers */\n allowNegativeNumbers?: boolean;\n /** Enable validation */\n validation?: boolean;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;AAGA;MACa,iBAAiB,GAAG,IAAI,cAAc,CAAkB,iBAAiB;AAEtF;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,eAAe,CAAC,MAAA,GAAyB,EAAE,EAAA;AACzD,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,iBAAiB;YAC1B,UAAU,EAAE,MAAM,IAAI,eAAe,CAAC,MAAM,CAAC;AAC9C,SAAA;AACD,QAAA;AACE,YAAA,OAAO,EAAE,eAAe;AACxB,YAAA,WAAW,EAAE,iBAAiB;AAC/B,SAAA;AACF,KAAA,CAAC;AACJ;;ACpCA,MAAM,cAAc,GAAG,YAAY;AAEnC;;AAEG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,SAAyB,EAAE,EAAA;AAC9D,IAAA,MAAM,YAAY,GAAG,IAAI,KAAK,IAAI;IAElC,OAAO;AACL,QAAA,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;QACrC,iBAAiB,EAAE,YAAY,GAAG,GAAG,GAAG,GAAG;QAC3C,aAAa,GAAG,YAAY,GAAG,GAAG,GAAG,GAAG,CAAc;AACtD,QAAA,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,IAAI,IAAI;KAC1D;AACH;AAEA;;;;;;;;;;;;;AAaG;AACG,SAAU,eAAe,CAAC,MAAA,GAAyB,EAAE,EAAA;AACzD,IAAA,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,GAAG,aAAa,CAAC,GAAG,CAAS,cAAc,CAAC,GAAG,IAAI;IAClG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,IAAI,IAAI;IAC7C,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC;IAE9C,OAAO,wBAAwB,CAAC,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;AAC1E;;ACtCA;;;AAGG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,uBAAuB,CAAC;AACtB,YAAA,UAAU,EAAE,OAAO;AACnB,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,WAAW,EAAE,KAAK;AAClB,YAAA,kBAAkB,EAAE,GAAG;SACxB,CAAC;AACH,KAAA,CAAC;AACJ;;ACbA;;;;;;;;;;;;AAYG;AACG,SAAU,aAAa,CAAC,MAAA,GAAuB,EAAE,EAAA;AACrD,IAAA,OAAO,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAClF;;AClBA;AAeA,MAAM,oBAAoB,CAAA;AAEL,IAAA,KAAA;AACA,IAAA,OAAA;AACA,IAAA,OAAA;AACA,IAAA,WAAA;AACA,IAAA,gBAAA;AACA,IAAA,UAAA;IANnB,WAAA,CACmB,KAAiB,EACjB,OAAe,EACf,OAAe,EACf,WAAoB,EACpB,gBAAyB,EACzB,UAAqD,EAAA;QALrD,IAAA,CAAA,KAAK,GAAL,KAAK;QACL,IAAA,CAAA,OAAO,GAAP,OAAO;QACP,IAAA,CAAA,OAAO,GAAP,OAAO;QACP,IAAA,CAAA,WAAW,GAAX,WAAW;QACX,IAAA,CAAA,gBAAgB,GAAhB,gBAAgB;QAChB,IAAA,CAAA,UAAU,GAAV,UAAU;IAC1B;AAEI,IAAA,cAAc,CAAC,IAAY,EAAA;AAChC,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC5B,aAAA,GAAG,CAAoB,CAAA,EAAG,IAAI,CAAC,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAC,OAAO,CAAA,CAAE;AAC9D,aAAA,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAuB,CAAC,CAAC,CAAC;AAEtD,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;AACrB,YAAA,OAAO,iBAAiB;QAC1B;AAEA,QAAA,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE;AAC5E,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC;cAC3B,IAAI,CAAC;AACF,iBAAA,GAAG,CAAkB,CAAA,EAAG,IAAI,CAAC,gBAAgB,CAAA,EAAG,IAAI,CAAA,EAAG,IAAI,CAAC,OAAO,CAAA,CAAE;iBACrE,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAqB,CAAC,CAAC;AACrD,cAAE,EAAE,CAAC,EAAqB,CAAC;QAE7B,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE;AAErD,QAAA,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAC3E,GAAG,CACD,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,MAC7B;AACC,YAAA,GAAG,QAAQ;AACX,YAAA,GAAG,aAAa;AAChB,YAAA,GAAG,eAAe;AAClB,YAAA,GAAI,IAAgC;SACrC,CAAsB,CAC1B,CACF;IACH;AACD;SAEe,sBAAsB,CACpC,IAAgB,EAChB,IAAI,GAAG,gBAAgB,EACvB,SAAS,GAAG,OAAO,EACnB,UAAU,GAAG,IAAI,EACjB,eAAwB,EACxB,SAAoD,EAAA;AAEpD,IAAA,OAAO,IAAI,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC;AAChG;AAEA,SAAS,mBAAmB,CAAC,WAAmB,EAAA;AAC9C,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAC1C,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAS,gBAAgB,CAAC,IAAI,WAAW;AAC5E,IAAA,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC;IACtC,OAAO,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACjD;AAEM,SAAU,iBAAiB,CAAC,MAAA,GAAmC,EAAE,EAAA;IACrE,MAAM,EACJ,WAAW,GAAG,IAAI,EAClB,eAAe,GAAG,gBAAgB,EAClC,aAAa,GAAG,OAAO,EACvB,sBAAsB,GAAG,IAAI,EAC7B,eAAe,EACf,qBAAqB,GACtB,GAAG,MAAM;AAEV,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,uBAAuB,CAAC;AACtB,YAAA,YAAY,EAAE,WAAW;AACzB,YAAA,MAAM,EAAE;AACN,gBAAA,OAAO,EAAE,eAAe;AACxB,gBAAA,UAAU,EAAE,CAAC,IAAgB,KAC3B,sBAAsB,CACpB,IAAI,EACJ,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,qBAAqB,CACtB;gBACH,IAAI,EAAE,CAAC,UAAU,CAAC;AACnB,aAAA;SACF,CAAC;QACF,qBAAqB,CAAC,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;AAC9D,KAAA,CAAC;AACJ;;ACxGA;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"shival99-z-ui-providers.mjs","sources":["../../../../libs/core-ui/providers/z-cache.provider.ts","../../../../libs/core-ui/providers/z-indexdb.provider.ts","../../../../libs/core-ui/providers/z-ngx-mask.provider.ts","../../../../libs/core-ui/providers/z-scrollbar.provider.ts","../../../../libs/core-ui/providers/z-theme.provider.ts","../../../../libs/core-ui/providers/z-translate.provider.ts","../../../../libs/core-ui/providers/types/z-ngx-mask.types.ts","../../../../libs/core-ui/providers/shival99-z-ui-providers.ts"],"sourcesContent":["import {\n type EnvironmentProviders,\n inject,\n InjectionToken,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { type ZCacheConfig, ZCacheService } from '@shival99/z-ui/services';\n\n/** Injection token for ZCacheService configuration */\nexport const Z_CACHE_CONFIG = new InjectionToken<ZCacheConfig>('Z_CACHE_CONFIG');\n\n/**\n * Provide Z-Cache service with configuration\n * @param config - Cache configuration with prefix and encrypt options\n *\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZCache({\n * prefix: 'myapp_',\n * encrypt: false, // Disable encryption for debugging\n * }),\n * ],\n * };\n * ```\n */\nexport function provideZCache(config: ZCacheConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: Z_CACHE_CONFIG,\n useValue: config,\n },\n provideEnvironmentInitializer(() => {\n const cacheConfig = inject(Z_CACHE_CONFIG);\n ZCacheService.configure(cacheConfig);\n }),\n ]);\n}\n","import { type EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { type ZIndexDbConfig, ZIndexDbService } from '@shival99/z-ui/services';\n\n/** Injection token for ZIndexDbService */\nexport const Z_INDEXDB_SERVICE = new InjectionToken<ZIndexDbService>('ZIndexDbService');\n\n/**\n * Provide Z-IndexDB service with configuration\n * @param config - IndexDB configuration with multi-store support\n *\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZIndexDb({\n * dbName: 'MyApp',\n * version: 1,\n * stores: [\n * { name: 'cache', encrypt: true },\n * { name: 'userData', encrypt: true, protectedKeys: ['profile'] },\n * { name: 'settings', encrypt: false },\n * ],\n * defaultStore: 'cache',\n * protectedKeys: ['token'],\n * }),\n * ],\n * };\n * ```\n */\nexport function provideZIndexDb(config: ZIndexDbConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: Z_INDEXDB_SERVICE,\n useFactory: () => new ZIndexDbService(config),\n },\n {\n provide: ZIndexDbService,\n useExisting: Z_INDEXDB_SERVICE,\n },\n ]);\n}\n","import { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { ZCacheService } from '@shival99/z-ui/services';\nimport { provideEnvironmentNgxMask } from 'ngx-mask';\nimport type { ZNgxMaskConfig } from './types/z-ngx-mask.types';\n\nconst LANG_CACHE_KEY = 'Z_LANGUAGE';\n\n/**\n * Get locale-specific mask configuration\n */\nfunction getMaskConfig(lang: string, config: ZNgxMaskConfig = {}) {\n const isVietnamese = lang === 'vi';\n\n return {\n validation: config.validation ?? true,\n thousandSeparator: isVietnamese ? ',' : '.',\n decimalMarker: (isVietnamese ? '.' : ',') as '.' | ',',\n allowNegativeNumbers: config.allowNegativeNumbers ?? true,\n };\n}\n\n/**\n * Provide Z-NgxMask with locale-aware configuration\n * @param config - Mask configuration\n *\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZNgxMask({ lang: 'vi' }),\n * ],\n * };\n * ```\n */\nexport function provideZNgxMask(config: ZNgxMaskConfig = {}): EnvironmentProviders {\n const savedLang = typeof window !== 'undefined' ? ZCacheService.get<string>(LANG_CACHE_KEY) : null;\n const lang = config.lang ?? savedLang ?? 'vi';\n const maskConfig = getMaskConfig(lang, config);\n\n return makeEnvironmentProviders([provideEnvironmentNgxMask(maskConfig)]);\n}\n","import { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { provideScrollbarOptions } from 'ngx-scrollbar';\n\n/**\n * Provides global scrollbar options for ngx-scrollbar\n * Use this in app.config.ts: providers: [provideZScrollbar()]\n */\nexport function provideZScrollbar(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideScrollbarOptions({\n visibility: 'hover',\n appearance: 'compact',\n withButtons: false,\n sensorThrottleTime: 200,\n }),\n ]);\n}\n","import { makeEnvironmentProviders, type EnvironmentProviders } from '@angular/core';\nimport { type ZThemeConfig, Z_THEME_CONFIG } from '@shival99/z-ui/services';\n\n/**\n * Provide theme configuration for the application\n * @param config - Theme configuration with defaultTheme and defaultDarkMode\n * @example\n * ```typescript\n * // In app.config.ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideZTheme({ defaultTheme: 'hospital', defaultDarkMode: false })\n * ]\n * };\n * ```\n */\nexport function provideZTheme(config: ZThemeConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: Z_THEME_CONFIG, useValue: config }]);\n}\n","/* eslint-disable @stylistic/indent */\nimport { HttpClient } from '@angular/common/http';\nimport { inject, makeEnvironmentProviders, provideAppInitializer, type EnvironmentProviders } from '@angular/core';\nimport {\n provideTranslateService,\n TranslateLoader,\n TranslateService,\n type TranslationObject,\n} from '@ngx-translate/core';\nimport { Z_UI_TRANSLATIONS, type ZUITranslations } from '@shival99/z-ui/i18n';\nimport { Z_LANG_CACHE_KEY, ZCacheService } from '@shival99/z-ui/services';\nimport { firstValueFrom, forkJoin, map, type Observable, of } from 'rxjs';\nimport { catchError } from 'rxjs/operators';\nimport type { ZTranslateProviderConfig } from './types/z-translate.types';\n\nclass ZTranslateHttpLoader implements TranslateLoader {\n public constructor(\n private readonly _http: HttpClient,\n private readonly _prefix: string,\n private readonly _suffix: string,\n private readonly _includeZUI: boolean,\n private readonly _zuiOverridePath?: string,\n private readonly _customZUI?: Partial<Record<string, ZUITranslations>>\n ) {}\n\n public getTranslation(lang: string): Observable<TranslationObject> {\n const userTranslations$ = this._http\n .get<TranslationObject>(`${this._prefix}${lang}${this._suffix}`)\n .pipe(catchError(() => of({} as TranslationObject)));\n\n if (!this._includeZUI) {\n return userTranslations$;\n }\n\n const zuiDefaults = Z_UI_TRANSLATIONS[lang] ?? Z_UI_TRANSLATIONS['en'] ?? {};\n const zuiFileOverrides$ = this._zuiOverridePath\n ? this._http\n .get<ZUITranslations>(`${this._zuiOverridePath}${lang}${this._suffix}`)\n .pipe(catchError(() => of({} as ZUITranslations)))\n : of({} as ZUITranslations);\n\n const inlineOverrides = this._customZUI?.[lang] ?? {};\n\n return forkJoin([of(zuiDefaults), zuiFileOverrides$, userTranslations$]).pipe(\n map(\n ([defaults, fileOverrides, user]) =>\n ({\n ...defaults,\n ...fileOverrides,\n ...inlineOverrides,\n ...(user as Record<string, unknown>),\n }) as TranslationObject\n )\n );\n }\n}\n\nexport function zCreateTranslateLoader(\n http: HttpClient,\n path = './assets/i18n/',\n extension = '.json',\n includeZUI = true,\n zuiOverridePath?: string,\n customZUI?: Partial<Record<string, ZUITranslations>>\n): TranslateLoader {\n return new ZTranslateHttpLoader(http, path, extension, includeZUI, zuiOverridePath, customZUI);\n}\n\nfunction initializeTranslate(defaultLang: string): Promise<unknown> {\n const translate = inject(TranslateService);\n const savedLang = ZCacheService.get<string>(Z_LANG_CACHE_KEY) ?? defaultLang;\n translate.setFallbackLang(defaultLang);\n return firstValueFrom(translate.use(savedLang));\n}\n\nexport function provideZTranslate(config: ZTranslateProviderConfig = {}): EnvironmentProviders {\n const {\n defaultLang = 'vi',\n translationPath = './assets/i18n/',\n fileExtension = '.json',\n includeZUITranslations = true,\n zuiOverridePath,\n customZUITranslations,\n } = config;\n\n return makeEnvironmentProviders([\n provideTranslateService({\n fallbackLang: defaultLang,\n loader: {\n provide: TranslateLoader,\n useFactory: (http: HttpClient) =>\n zCreateTranslateLoader(\n http,\n translationPath,\n fileExtension,\n includeZUITranslations,\n zuiOverridePath,\n customZUITranslations\n ),\n deps: [HttpClient],\n },\n }),\n provideAppInitializer(() => initializeTranslate(defaultLang)),\n ]);\n}\n\nexport { Z_UI_TRANSLATIONS, mergeTranslations, getZUITranslations } from '@shival99/z-ui/i18n';\nexport type { ZUITranslations, ZUILanguage, ZUITranslationSet } from '@shival99/z-ui/i18n';\n","/**\n * Z-NgxMask Provider Types\n */\n\nexport interface ZNgxMaskConfig {\n /** Language code (vi, en, etc.) */\n lang?: string;\n /** Allow negative numbers */\n allowNegativeNumbers?: boolean;\n /** Enable validation */\n validation?: boolean;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -10,9 +10,8 @@ import { firstValueFrom, from, switchMap, of, catchError, throwError, tap, map,
10
10
  import { TranslateService } from '@ngx-translate/core';
11
11
  import { DOCUMENT, isPlatformBrowser } from '@angular/common';
12
12
 
13
- const Z_CACHE_DEFAULT_PREFIX = 'z_';
14
13
  class ZCacheService {
15
- static _prefix = Z_CACHE_DEFAULT_PREFIX;
14
+ static _prefix = 'z_';
16
15
  static _encrypt = true;
17
16
  static configure(config) {
18
17
  if (config.prefix) {
@@ -38,8 +37,12 @@ class ZCacheService {
38
37
  return null;
39
38
  }
40
39
  }
40
+ static _normalizeKey(key) {
41
+ return key.toLowerCase();
42
+ }
41
43
  static _getFullKey(key, encrypt) {
42
- const prefixedKey = `${ZCacheService._prefix}${key}`;
44
+ const normalizedKey = ZCacheService._normalizeKey(key);
45
+ const prefixedKey = `${ZCacheService._prefix}${normalizedKey}`;
43
46
  return encrypt ? ZCacheService._encode(prefixedKey) : prefixedKey;
44
47
  }
45
48
  static _safeOperation(operation, fallback) {
@@ -51,12 +54,6 @@ class ZCacheService {
51
54
  return fallback;
52
55
  }
53
56
  }
54
- /**
55
- * Get a value from cache
56
- * @param key - Cache key
57
- * @param defaultValue - Default value if not found
58
- * @param encrypt - Whether to use encryption (default: service config)
59
- */
60
57
  static get(key, defaultValue, encrypt = ZCacheService._encrypt) {
61
58
  return ZCacheService._safeOperation(() => {
62
59
  const _key = ZCacheService._getFullKey(key, encrypt);
@@ -68,12 +65,6 @@ class ZCacheService {
68
65
  return data ?? defaultValue;
69
66
  }, defaultValue);
70
67
  }
71
- /**
72
- * Set a value in cache
73
- * @param key - Cache key
74
- * @param data - Data to store
75
- * @param encrypt - Whether to use encryption
76
- */
77
68
  static set(key, data, encrypt = ZCacheService._encrypt) {
78
69
  return ZCacheService._safeOperation(() => {
79
70
  const _key = ZCacheService._getFullKey(key, encrypt);
@@ -82,35 +73,26 @@ class ZCacheService {
82
73
  return true;
83
74
  }, false);
84
75
  }
85
- /**
86
- * Delete a key from cache
87
- * @param key - Cache key
88
- * @param encrypt - Whether key is encrypted
89
- */
90
- static delete(key, encrypt = ZCacheService._encrypt) {
76
+ static delete(key) {
91
77
  return ZCacheService._safeOperation(() => {
92
- const _key = ZCacheService._getFullKey(key, encrypt);
93
- localStorage.removeItem(_key);
78
+ const encryptedKey = ZCacheService._getFullKey(key, true);
79
+ const plainKey = ZCacheService._getFullKey(key, false);
80
+ localStorage.removeItem(encryptedKey);
81
+ localStorage.removeItem(plainKey);
94
82
  return true;
95
83
  }, false);
96
84
  }
97
- /**
98
- * Delete multiple keys from cache
99
- * @param keys - Array of cache keys
100
- * @param encrypt - Whether keys are encrypted
101
- */
102
- static deleteMultiple(keys, encrypt = ZCacheService._encrypt) {
85
+ static deleteMultiple(keys) {
103
86
  return ZCacheService._safeOperation(() => {
104
87
  keys.forEach(key => {
105
- const _key = ZCacheService._getFullKey(key, encrypt);
106
- localStorage.removeItem(_key);
88
+ const encryptedKey = ZCacheService._getFullKey(key, true);
89
+ const plainKey = ZCacheService._getFullKey(key, false);
90
+ localStorage.removeItem(encryptedKey);
91
+ localStorage.removeItem(plainKey);
107
92
  });
108
93
  return true;
109
94
  }, false);
110
95
  }
111
- /**
112
- * Clear all cache with the configured prefix
113
- */
114
96
  static clear() {
115
97
  return ZCacheService._safeOperation(() => {
116
98
  const keysToRemove = [];
@@ -125,20 +107,12 @@ class ZCacheService {
125
107
  return true;
126
108
  }, false);
127
109
  }
128
- /**
129
- * Check if a key exists in cache
130
- * @param key - Cache key
131
- * @param encrypt - Whether key is encrypted
132
- */
133
110
  static has(key, encrypt = ZCacheService._encrypt) {
134
111
  return ZCacheService._safeOperation(() => {
135
112
  const _key = ZCacheService._getFullKey(key, encrypt);
136
113
  return localStorage.getItem(_key) !== null;
137
114
  }, false);
138
115
  }
139
- /**
140
- * Get all keys with the configured prefix
141
- */
142
116
  static keys() {
143
117
  return ZCacheService._safeOperation(() => {
144
118
  const result = [];
@@ -147,8 +121,9 @@ class ZCacheService {
147
121
  const key = localStorage.key(i);
148
122
  if (key?.startsWith(ZCacheService._prefix)) {
149
123
  result.push(key.slice(ZCacheService._prefix.length));
124
+ continue;
150
125
  }
151
- else if (key?.startsWith(prefixEncoded)) {
126
+ if (key?.startsWith(prefixEncoded)) {
152
127
  const decoded = ZCacheService._decode(key);
153
128
  if (decoded) {
154
129
  result.push(decoded.slice(ZCacheService._prefix.length));
@@ -935,25 +910,42 @@ class ZIndexDbService {
935
910
  _stores = new Map();
936
911
  _defaultStoreName;
937
912
  _globalProtectedKeys;
913
+ _encrypt = true;
938
914
  constructor(config = {}) {
939
915
  this._dbName = config.dbName ?? Z_INDEXDB_DEFAULT_CONFIG.dbName;
940
916
  this._version = config.version ?? Z_INDEXDB_DEFAULT_CONFIG.version;
941
917
  this._mode = config.mode ?? Z_INDEXDB_DEFAULT_CONFIG.mode;
942
918
  this._defaultStoreName = config.defaultStore ?? Z_INDEXDB_DEFAULT_CONFIG.defaultStore;
943
919
  this._globalProtectedKeys = config.protectedKeys ?? [];
920
+ this._encrypt = config.encrypt ?? true;
944
921
  if (config.stores?.length) {
945
922
  config.stores.forEach(store => this._stores.set(store.name, store));
946
923
  }
947
924
  if (!this._stores.has(this._defaultStoreName)) {
948
- this._stores.set(this._defaultStoreName, { name: this._defaultStoreName, encrypt: true });
925
+ this._stores.set(this._defaultStoreName, { name: this._defaultStoreName });
949
926
  }
950
927
  this._dbReady = this._initDb();
951
928
  }
952
929
  _getStoreConfig(storeName) {
953
930
  const name = storeName ?? this._defaultStoreName;
954
- return this._stores.get(name) ?? { name, encrypt: true };
931
+ return this._stores.get(name) ?? { name };
932
+ }
933
+ /**
934
+ * Determines if encryption should be used.
935
+ * Priority: per-call > store-level > global
936
+ * @param storeConfig - Store configuration
937
+ * @param perCallEncrypt - Per-call encrypt override (highest priority)
938
+ */
939
+ _shouldEncrypt(storeConfig, perCallEncrypt) {
940
+ if (perCallEncrypt !== undefined) {
941
+ return perCallEncrypt;
942
+ }
943
+ return storeConfig.encrypt ?? this._encrypt;
955
944
  }
956
- _encrypt(data) {
945
+ _normalizeKey(key) {
946
+ return key.toLowerCase();
947
+ }
948
+ _encryptData(data) {
957
949
  const payload = {
958
950
  __z: true,
959
951
  __t: typeof data,
@@ -961,7 +953,7 @@ class ZIndexDbService {
961
953
  };
962
954
  return btoa(encodeURIComponent(JSON.stringify(payload)));
963
955
  }
964
- _decrypt(data) {
956
+ _decryptData(data) {
965
957
  try {
966
958
  const decoded = JSON.parse(decodeURIComponent(atob(data)));
967
959
  if (!decoded.__z) {
@@ -1009,7 +1001,7 @@ class ZIndexDbService {
1009
1001
  await this._resetDatabase();
1010
1002
  this._version = 1;
1011
1003
  }
1012
- else if (currentVersion > this._version) {
1004
+ if (currentVersion > this._version && currentVersion < Z_INDEXDB_MAX_VERSION) {
1013
1005
  this._version = currentVersion;
1014
1006
  }
1015
1007
  return new Promise((resolve, reject) => {
@@ -1102,8 +1094,10 @@ class ZIndexDbService {
1102
1094
  }
1103
1095
  return this._db.objectStoreNames.contains(storeName);
1104
1096
  }
1105
- async get(key, defaultValue, storeName) {
1106
- const storeConfig = this._getStoreConfig(storeName);
1097
+ async get(key, options) {
1098
+ const storeConfig = this._getStoreConfig(options?.storeName);
1099
+ const shouldEncrypt = this._shouldEncrypt(storeConfig, options?.encrypt);
1100
+ const defaultValue = options?.defaultValue;
1107
1101
  return this._withRetry(async () => {
1108
1102
  await this._dbReady;
1109
1103
  if (!this._db) {
@@ -1118,7 +1112,8 @@ class ZIndexDbService {
1118
1112
  return defaultValue;
1119
1113
  }
1120
1114
  }
1121
- const _key = storeConfig.encrypt !== false ? this._encrypt(key) : key;
1115
+ const normalizedKey = this._normalizeKey(key);
1116
+ const _key = shouldEncrypt ? this._encryptData(normalizedKey) : normalizedKey;
1122
1117
  return new Promise(resolve => {
1123
1118
  try {
1124
1119
  const transaction = this._db.transaction([storeConfig.name], this._mode);
@@ -1131,7 +1126,7 @@ class ZIndexDbService {
1131
1126
  resolve(defaultValue);
1132
1127
  return;
1133
1128
  }
1134
- const decrypted = storeConfig.encrypt !== false ? this._decrypt(result) : result;
1129
+ const decrypted = shouldEncrypt ? this._decryptData(result) : result;
1135
1130
  resolve(decrypted ?? defaultValue);
1136
1131
  }
1137
1132
  catch {
@@ -1147,8 +1142,9 @@ class ZIndexDbService {
1147
1142
  });
1148
1143
  });
1149
1144
  }
1150
- async set(key, value, storeName) {
1151
- const storeConfig = this._getStoreConfig(storeName);
1145
+ async set(key, value, options) {
1146
+ const storeConfig = this._getStoreConfig(options?.storeName);
1147
+ const shouldEncrypt = this._shouldEncrypt(storeConfig, options?.encrypt);
1152
1148
  return this._withRetry(async () => {
1153
1149
  await this._dbReady;
1154
1150
  if (!this._db) {
@@ -1163,8 +1159,9 @@ class ZIndexDbService {
1163
1159
  throw new Error(`Failed to create store "${storeConfig.name}"`);
1164
1160
  }
1165
1161
  }
1166
- const _key = storeConfig.encrypt !== false ? this._encrypt(key) : key;
1167
- const _value = storeConfig.encrypt !== false ? this._encrypt(value) : value;
1162
+ const normalizedKey = this._normalizeKey(key);
1163
+ const _key = shouldEncrypt ? this._encryptData(normalizedKey) : normalizedKey;
1164
+ const _value = shouldEncrypt ? this._encryptData(value) : value;
1168
1165
  return new Promise((resolve, reject) => {
1169
1166
  try {
1170
1167
  const transaction = this._db.transaction([storeConfig.name], 'readwrite');
@@ -1180,7 +1177,18 @@ class ZIndexDbService {
1180
1177
  });
1181
1178
  });
1182
1179
  }
1180
+ /**
1181
+ * Delete key(s) from IndexDB. If storeName not provided, deletes from all stores.
1182
+ * Tries both encrypted and non-encrypted versions of the key.
1183
+ */
1183
1184
  async delete(key, storeName) {
1185
+ if (storeName === undefined) {
1186
+ await Promise.all(this.getStoreNames().map(name => this._deleteFromStore(key, name)));
1187
+ return;
1188
+ }
1189
+ await this._deleteFromStore(key, storeName);
1190
+ }
1191
+ async _deleteFromStore(key, storeName) {
1184
1192
  const storeConfig = this._getStoreConfig(storeName);
1185
1193
  return this._withRetry(async () => {
1186
1194
  await this._dbReady;
@@ -1199,8 +1207,9 @@ class ZIndexDbService {
1199
1207
  const transaction = this._db.transaction([storeConfig.name], 'readwrite');
1200
1208
  const store = transaction.objectStore(storeConfig.name);
1201
1209
  keys.forEach(k => {
1202
- const _key = storeConfig.encrypt !== false ? this._encrypt(k) : k;
1203
- store.delete(_key);
1210
+ const normalizedKey = this._normalizeKey(k);
1211
+ store.delete(normalizedKey);
1212
+ store.delete(this._encryptData(normalizedKey));
1204
1213
  });
1205
1214
  transaction.oncomplete = () => resolve();
1206
1215
  transaction.onerror = () => reject(transaction.error);
@@ -1239,18 +1248,18 @@ class ZIndexDbService {
1239
1248
  const transaction = this._db.transaction([storeConfig.name], 'readwrite');
1240
1249
  const store = transaction.objectStore(storeConfig.name);
1241
1250
  const keyRequest = store.getAllKeys();
1251
+ const protectedSet = new Set();
1252
+ protectedKeys.forEach(k => {
1253
+ const normalizedKey = this._normalizeKey(k);
1254
+ protectedSet.add(normalizedKey);
1255
+ protectedSet.add(this._encryptData(normalizedKey));
1256
+ });
1242
1257
  keyRequest.onsuccess = () => {
1243
1258
  const allKeys = keyRequest.result;
1244
- const encryptedProtected = protectedKeys.map(k => this._encrypt(k));
1245
1259
  allKeys.forEach(k => {
1246
- if (!encryptedProtected.includes(k) && !protectedKeys.includes(k)) {
1247
- try {
1248
- const decrypted = this._decrypt(k);
1249
- if (!protectedKeys.includes(decrypted ?? '')) {
1250
- store.delete(k);
1251
- }
1252
- }
1253
- catch {
1260
+ if (!protectedSet.has(k)) {
1261
+ const decrypted = this._decryptData(k);
1262
+ if (!decrypted || !protectedKeys.includes(decrypted)) {
1254
1263
  store.delete(k);
1255
1264
  }
1256
1265
  }
@@ -1292,14 +1301,14 @@ class ZIndexDbService {
1292
1301
  keys.forEach((key, index) => {
1293
1302
  if (typeof key === 'string') {
1294
1303
  try {
1295
- const _key = storeConfig.encrypt !== false ? this._decrypt(key) : key;
1296
- const _value = storeConfig.encrypt !== false ? this._decrypt(values[index]) : values[index];
1304
+ const _key = this._shouldEncrypt(storeConfig) ? this._decryptData(key) : key;
1305
+ const _value = this._shouldEncrypt(storeConfig) ? this._decryptData(values[index]) : values[index];
1297
1306
  if (_key && _value !== null) {
1298
1307
  results[_key] = _value;
1299
1308
  }
1300
1309
  }
1301
1310
  catch {
1302
- // Skip
1311
+ console.warn(`[ZIndexDb] Failed to decrypt entry for key: ${key}`);
1303
1312
  }
1304
1313
  }
1305
1314
  });
@@ -1314,8 +1323,9 @@ class ZIndexDbService {
1314
1323
  });
1315
1324
  });
1316
1325
  }
1317
- async setMultiple(items, storeName) {
1318
- const storeConfig = this._getStoreConfig(storeName);
1326
+ async setMultiple(items, options) {
1327
+ const storeConfig = this._getStoreConfig(options?.storeName);
1328
+ const shouldEncrypt = this._shouldEncrypt(storeConfig, options?.encrypt);
1319
1329
  const entries = Object.entries(items);
1320
1330
  await this._dbReady;
1321
1331
  if (this._db && !this._ensureStoreExists(storeConfig.name)) {
@@ -1338,8 +1348,9 @@ class ZIndexDbService {
1338
1348
  const transaction = this._db.transaction([storeConfig.name], 'readwrite');
1339
1349
  const store = transaction.objectStore(storeConfig.name);
1340
1350
  batch.forEach(([key, value]) => {
1341
- const _key = storeConfig.encrypt !== false ? this._encrypt(key) : key;
1342
- const _value = storeConfig.encrypt !== false ? this._encrypt(value) : value;
1351
+ const normalizedKey = this._normalizeKey(key);
1352
+ const _key = shouldEncrypt ? this._encryptData(normalizedKey) : normalizedKey;
1353
+ const _value = shouldEncrypt ? this._encryptData(value) : value;
1343
1354
  store.put(_value, _key);
1344
1355
  });
1345
1356
  transaction.oncomplete = () => resolve();
@@ -1361,6 +1372,10 @@ class ZIndexDbService {
1361
1372
  this._stores.set(config.name, config);
1362
1373
  await this._triggerUpgrade();
1363
1374
  }
1375
+ async clearAll() {
1376
+ const storeNames = this.getStoreNames();
1377
+ await Promise.all(storeNames.map(storeName => this.clear(storeName)));
1378
+ }
1364
1379
  }
1365
1380
 
1366
1381
  const Z_LANG_TO_LOCALE = {
@@ -1688,11 +1703,11 @@ class ZHttpAbstractService {
1688
1703
  }
1689
1704
  async _cacheData(key, data, ttl) {
1690
1705
  const cacheEntry = { data, timestamp: Date.now(), ttl };
1691
- await this.indexDbService.set(key, cacheEntry, 'HttpCache');
1706
+ await this.indexDbService.set(key, cacheEntry, { storeName: 'HttpCache' });
1692
1707
  }
1693
1708
  async _getCachedData(key) {
1694
1709
  try {
1695
- const cached = await this.indexDbService.get(key, undefined, 'HttpCache');
1710
+ const cached = await this.indexDbService.get(key, { storeName: 'HttpCache' });
1696
1711
  if (!cached) {
1697
1712
  return null;
1698
1713
  }
@@ -2027,7 +2042,7 @@ class ZThemeService {
2027
2042
  if (this._hasConfigChanged()) {
2028
2043
  return this._defaultTheme;
2029
2044
  }
2030
- return ZCacheService.get(Z_THEME_CACHE_KEY, undefined, true) ?? this._defaultTheme;
2045
+ return ZCacheService.get(Z_THEME_CACHE_KEY, undefined) ?? this._defaultTheme;
2031
2046
  }
2032
2047
  _getInitialDarkMode() {
2033
2048
  if (!this._isBrowser) {
@@ -2039,7 +2054,7 @@ class ZThemeService {
2039
2054
  return ZCacheService.get(Z_DARK_MODE_CACHE_KEY, undefined, true) ?? this._defaultDarkMode;
2040
2055
  }
2041
2056
  _hasConfigChanged() {
2042
- const cachedConfig = ZCacheService.get(Z_THEME_CONFIG_CACHE_KEY, undefined, true);
2057
+ const cachedConfig = ZCacheService.get(Z_THEME_CONFIG_CACHE_KEY, undefined);
2043
2058
  if (!cachedConfig) {
2044
2059
  return true;
2045
2060
  }
@@ -2055,7 +2070,7 @@ class ZThemeService {
2055
2070
  defaultTheme: this._defaultTheme,
2056
2071
  defaultDarkMode: this._defaultDarkMode,
2057
2072
  };
2058
- ZCacheService.set(Z_THEME_CONFIG_CACHE_KEY, currentConfig, true);
2073
+ ZCacheService.set(Z_THEME_CONFIG_CACHE_KEY, currentConfig);
2059
2074
  }
2060
2075
  _loadThemeCSS(theme, onLoad) {
2061
2076
  const cssPath = Z_THEME_CSS_MAP[theme];