@reforgium/presentia 1.5.0 → 2.1.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/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
- "version": "1.5.0",
2
+ "version": "2.1.0",
3
3
  "name": "@reforgium/presentia",
4
- "description": "Angular app infrastructure for localization, theme, adaptive behavior, routes, and SEO",
4
+ "description": "Angular infrastructure library for i18n, route-aware namespace preload, theming, adaptive breakpoints, route state, and SEO",
5
5
  "author": "rtommievich",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "repository": {
9
- "type": "git"
9
+ "type": "git",
10
+ "directory": "libs/presentia"
10
11
  },
11
12
  "bugs": {
12
13
  "email": "rtommievich@gmail.com"
@@ -20,15 +21,28 @@
20
21
  "npm": ">=9.0.0"
21
22
  },
22
23
  "bin": {
23
- "presentia-gen-lang-keys": "./bin/presentia-gen-lang-keys.mjs"
24
+ "presentia-gen-lang-keys": "./bin/presentia-gen-lang-keys.mjs",
25
+ "presentia-gen-namespaces": "./bin/presentia-gen-namespaces.mjs"
24
26
  },
25
27
  "keywords": [
26
28
  "reforgium",
29
+ "angular-library",
27
30
  "infrastructure",
28
31
  "i18n",
32
+ "localization",
33
+ "internationalization",
34
+ "i18n",
35
+ "translation",
36
+ "namespace-preload",
37
+ "route-preload",
29
38
  "theme",
39
+ "theming",
40
+ "adaptive",
41
+ "responsive",
42
+ "breakpoints",
43
+ "route-state",
44
+ "signals",
30
45
  "seo",
31
- "signal",
32
46
  "angular"
33
47
  ],
34
48
  "types": "../../dist/@reforgium/presentia/index.d.ts",
@@ -38,6 +52,8 @@
38
52
  "bin/*.mjs",
39
53
  "package.json",
40
54
  "README.md",
55
+ "V2-MIGRATION.md",
56
+ "V2-CONFIG.md",
41
57
  "CHANGELOG.md",
42
58
  "LICENSE*"
43
59
  ],
@@ -47,7 +63,9 @@
47
63
  "peerDependencies": {
48
64
  "@angular/common": ">=18.0.0",
49
65
  "@angular/core": ">=18.0.0",
50
- "@reforgium/internal": ">=1.2.0",
66
+ "@angular/platform-browser": ">=18.0.0",
67
+ "@angular/router": ">=18.0.0",
68
+ "@reforgium/internal": ">=2.0.0",
51
69
  "rxjs": ">=7.0.0"
52
70
  },
53
71
  "module": "fesm2022/reforgium-presentia.mjs",
@@ -1,7 +1,7 @@
1
- import * as i0 from '@angular/core';
1
+ import * as _angular_core from '@angular/core';
2
2
  import { InjectionToken, Signal, PipeTransform, EnvironmentProviders } from '@angular/core';
3
3
  import * as _reforgium_internal from '@reforgium/internal';
4
- import { Devices, Langs, Themes } from '@reforgium/internal';
4
+ import { Devices, Langs, StorageInterface, Themes as Themes$1, StorageStrategy } from '@reforgium/internal';
5
5
  import { HttpHeaders, HttpParams, HttpContext } from '@angular/common/http';
6
6
 
7
7
  /** Breakpoints for different device types */
@@ -75,27 +75,30 @@ declare class AdaptiveService {
75
75
  * Updates automatically when screen width changes
76
76
  * or when specified breakpoints are crossed (`DEVICE_BREAKPOINTS`).
77
77
  */
78
- device: i0.Signal<Devices>;
78
+ device: _angular_core.Signal<Devices>;
79
79
  /**
80
80
  * Current browser window width in pixels.
81
81
  * Updates reactively on `resize` event.
82
82
  */
83
- width: i0.Signal<number>;
83
+ width: _angular_core.Signal<number>;
84
84
  /**
85
85
  * Current browser window height in pixels.
86
86
  * Updates reactively on `resize` event.
87
87
  */
88
- height: i0.Signal<number>;
88
+ height: _angular_core.Signal<number>;
89
89
  /**
90
90
  * Computed signal indicating whether the current device is a desktop.
91
91
  * Used for conditional rendering or layout configuration.
92
92
  */
93
- isDesktop: i0.Signal<boolean>;
93
+ isDesktop: _angular_core.Signal<boolean>;
94
+ isMobile: _angular_core.Signal<boolean>;
95
+ isTablet: _angular_core.Signal<boolean>;
96
+ isDesktopSmall: _angular_core.Signal<boolean>;
94
97
  /**
95
98
  * Computed signal determining whether the screen is in portrait orientation.
96
99
  * Returns `true` if window height is greater than width.
97
100
  */
98
- isPortrait: i0.Signal<boolean>;
101
+ isPortrait: _angular_core.Signal<boolean>;
99
102
  private deviceBreakpoints;
100
103
  private devicePriority;
101
104
  private destroyRef;
@@ -103,8 +106,13 @@ declare class AdaptiveService {
103
106
  private isBrowser;
104
107
  private resizeDebounceId;
105
108
  constructor();
106
- static ɵfac: i0.ɵɵFactoryDeclaration<AdaptiveService, never>;
107
- static ɵprov: i0.ɵɵInjectableDeclaration<AdaptiveService>;
109
+ breakpoint(): Devices;
110
+ is(device: Devices | readonly Devices[]): boolean;
111
+ isAtLeast(device: Devices): boolean;
112
+ isBetween(min: Devices, max: Devices): boolean;
113
+ private deviceRank;
114
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AdaptiveService, never>;
115
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<AdaptiveService>;
108
116
  }
109
117
 
110
118
  /**
@@ -129,6 +137,8 @@ declare class AdaptiveService {
129
137
  */
130
138
  declare class IfDeviceDirective {
131
139
  private readonly deviceInput;
140
+ private readonly atLeastInput;
141
+ private readonly betweenInput;
132
142
  private readonly inverseInput;
133
143
  private readonly tpl;
134
144
  private readonly vcr;
@@ -138,10 +148,12 @@ declare class IfDeviceDirective {
138
148
  private readonly currentDevice;
139
149
  constructor();
140
150
  set reIfDevice(value: Devices | Devices[] | undefined);
151
+ set reIfDeviceAtLeast(value: Devices | undefined);
152
+ set reIfDeviceBetween(value: readonly [Devices, Devices] | undefined);
141
153
  set inverse(value: boolean | undefined);
142
154
  private updateView;
143
- static ɵfac: i0.ɵɵFactoryDeclaration<IfDeviceDirective, never>;
144
- static ɵdir: i0.ɵɵDirectiveDeclaration<IfDeviceDirective, "[reIfDevice]", never, { "reIfDevice": { "alias": "reIfDevice"; "required": false; }; "inverse": { "alias": "inverse"; "required": false; }; }, {}, never, never, true, never>;
155
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<IfDeviceDirective, never>;
156
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<IfDeviceDirective, "[reIfDevice],[reIfDeviceAtLeast],[reIfDeviceBetween]", never, { "reIfDevice": { "alias": "reIfDevice"; "required": false; }; "reIfDeviceAtLeast": { "alias": "reIfDeviceAtLeast"; "required": false; }; "reIfDeviceBetween": { "alias": "reIfDeviceBetween"; "required": false; }; "inverse": { "alias": "inverse"; "required": false; }; }, {}, never, never, true, never>;
145
157
  }
146
158
 
147
159
  /**
@@ -222,6 +234,35 @@ type LangNamespaceCacheConfig = {
222
234
  maxNamespaces?: number;
223
235
  ttlMs?: number;
224
236
  };
237
+ type LangRouteNamespaceManifest = Record<string, readonly string[]>;
238
+ type LangRouteNamespacePreloadMode = 'blocking' | 'lazy';
239
+ type LangRouteNamespacePreloadMergeStrategy = 'append' | 'replace';
240
+ type LangRouteNamespacePreloadErrorMode = 'continue' | 'throw';
241
+ type LangRouteNamespacePreloadConfig = {
242
+ mode?: LangRouteNamespacePreloadMode;
243
+ dataKey?: string;
244
+ manifest?: LangRouteNamespaceManifest;
245
+ mergeStrategy?: LangRouteNamespacePreloadMergeStrategy;
246
+ onError?: LangRouteNamespacePreloadErrorMode;
247
+ diagnostics?: boolean;
248
+ };
249
+ /**
250
+ * Adapter for custom persistence of language/theme selection.
251
+ * Implement this interface to replace the default `localStorage` storage.
252
+ */
253
+ type PersistenceAdapter = StorageInterface<string, string>;
254
+ /**
255
+ * Describes a failed namespace load attempt.
256
+ * Exposed via `LangService.errors()` signal.
257
+ */
258
+ type LoadNamespaceError = {
259
+ namespace: string;
260
+ lang: Langs;
261
+ /** HTTP status code, or `null` for non-HTTP failures. */
262
+ status: number | null;
263
+ /** Request URL that produced the error. */
264
+ url: string;
265
+ };
225
266
  /**
226
267
  * Represents configuration settings for localization.
227
268
  *
@@ -244,6 +285,7 @@ type LangNamespaceCacheConfig = {
244
285
  * - `batchRequestBuilder` optional URL builder hook for batched namespace loading.
245
286
  * - `batchResponseAdapter` optional transformer hook for batched API payloads.
246
287
  * - `namespaceCache` optional ttl/lru-like cache controls for loaded namespaces.
288
+ * - `routeNamespacePreload` optional route-aware namespace preload settings.
247
289
  */
248
290
  interface LocaleConfig {
249
291
  url: string;
@@ -260,11 +302,32 @@ interface LocaleConfig {
260
302
  batchRequestBuilder?: LangBatchRequestBuilder;
261
303
  batchResponseAdapter?: LangBatchResponseAdapter;
262
304
  namespaceCache?: LangNamespaceCacheConfig;
305
+ routeNamespacePreload?: LangRouteNamespacePreloadConfig;
306
+ /**
307
+ * Maximum number of namespaces per batch request.
308
+ * When the namespace list exceeds this limit the load is split into multiple batch requests.
309
+ * No limit by default.
310
+ */
311
+ maxBatchSize?: number;
263
312
  }
264
313
  declare const innerLangVal: unique symbol;
265
314
 
266
315
  declare const LANG_MISSING_KEY_HANDLER: InjectionToken<LangMissingKeyHandler>;
267
316
 
317
+ /**
318
+ * Optional DI token for a custom persistence adapter used by `LangService`
319
+ * to store and retrieve the selected language (default key: `'lang'`).
320
+ *
321
+ * When not provided the service falls back to `localStorage` directly.
322
+ *
323
+ * Example:
324
+ * ```ts
325
+ * { provide: LANG_PERSISTENCE_ADAPTER, useValue: sessionStorageAdapter }
326
+ * ```
327
+ */
328
+ declare const defaultLangPersistenceAdapter: StorageInterface<string, string>;
329
+ declare const LANG_PERSISTENCE_ADAPTER: InjectionToken<PersistenceAdapter>;
330
+
268
331
  /**
269
332
  * Injection token for providing locale configuration to the language module.
270
333
  *
@@ -313,7 +376,9 @@ declare class LangService {
313
376
  private readonly config;
314
377
  private readonly http;
315
378
  private readonly isBrowser;
379
+ private readonly persistence;
316
380
  private readonly missingKeyHandler;
381
+ private readonly routeNamespaceDiagnostics;
317
382
  private readonly supportedLangSet;
318
383
  /**
319
384
  * Computed property determining the current language setting.
@@ -371,6 +436,9 @@ declare class LangService {
371
436
  loadNamespace(ns: string): Promise<void>;
372
437
  isNamespaceLoaded(ns: string): boolean;
373
438
  loadNamespaces(namespaces: readonly string[]): Promise<void>;
439
+ private loadNamespaceBatch;
440
+ private normalizeMaxBatchSize;
441
+ private chunkNamespaces;
374
442
  evictNamespace(ns: string): void;
375
443
  clearNamespaceCache(): void;
376
444
  private parseModelToRecord;
@@ -396,8 +464,8 @@ declare class LangService {
396
464
  private resolveMissingValue;
397
465
  private normalizeLang;
398
466
  private normalizeSupportedLangs;
399
- static ɵfac: i0.ɵɵFactoryDeclaration<LangService, never>;
400
- static ɵprov: i0.ɵɵInjectableDeclaration<LangService>;
467
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<LangService, never>;
468
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<LangService>;
401
469
  }
402
470
 
403
471
  /**
@@ -448,7 +516,7 @@ declare class LangDirective {
448
516
  * Localization mode: defines which parts of the element will be translated.
449
517
  * @default 'all'
450
518
  */
451
- lang: i0.InputSignal<string | LangDirectiveConfig>;
519
+ lang: _angular_core.InputSignal<string | LangDirectiveConfig>;
452
520
  /**
453
521
  * Explicit key for text content translation.
454
522
  */
@@ -460,7 +528,7 @@ declare class LangDirective {
460
528
  /**
461
529
  * Name of an additional attribute to localize (besides standard `title`, `label`, `placeholder`).
462
530
  */
463
- langForAttr: i0.InputSignal<string | undefined>;
531
+ langForAttr: _angular_core.InputSignal<string | undefined>;
464
532
  private el;
465
533
  private renderer;
466
534
  private service;
@@ -512,8 +580,8 @@ declare class LangDirective {
512
580
  * @returns localized string
513
581
  */
514
582
  private getLangValue;
515
- static ɵfac: i0.ɵɵFactoryDeclaration<LangDirective, never>;
516
- static ɵdir: i0.ɵɵDirectiveDeclaration<LangDirective, "[reLang]", never, { "lang": { "alias": "reLang"; "required": false; "isSignal": true; }; "langForAttr": { "alias": "langForAttr"; "required": false; "isSignal": true; }; "reLangKey": { "alias": "reLangKey"; "required": false; }; "reLangAttrs": { "alias": "reLangAttrs"; "required": false; }; }, {}, never, never, true, never>;
583
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<LangDirective, never>;
584
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<LangDirective, "[reLang]", never, { "lang": { "alias": "reLang"; "required": false; "isSignal": true; }; "langForAttr": { "alias": "langForAttr"; "required": false; "isSignal": true; }; "reLangKey": { "alias": "reLangKey"; "required": false; }; "reLangAttrs": { "alias": "reLangAttrs"; "required": false; }; }, {}, never, never, true, never>;
517
585
  }
518
586
 
519
587
  /**
@@ -543,8 +611,8 @@ declare class LangPipe implements PipeTransform {
543
611
  private makeKey;
544
612
  private evictIfNeeded;
545
613
  private warnUnresolvedKey;
546
- static ɵfac: i0.ɵɵFactoryDeclaration<LangPipe, never>;
547
- static ɵpipe: i0.ɵɵPipeDeclaration<LangPipe, "lang", true>;
614
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<LangPipe, never>;
615
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<LangPipe, "lang", true>;
548
616
  }
549
617
 
550
618
  type LangPipeConfig = {
@@ -554,21 +622,49 @@ type LangPipeConfig = {
554
622
  };
555
623
  declare const LANG_PIPE_CONFIG: InjectionToken<LangPipeConfig>;
556
624
 
625
+ type BaseTheme = _reforgium_internal.Themes;
626
+ type Theme = BaseTheme | (string & {});
627
+ /**
628
+ * @deprecated Prefer `Theme`.
629
+ */
630
+ type Themes = Theme;
631
+
632
+ type ThemeDomStrategy = 'root-class' | 'data-attribute';
633
+ type ThemeClassNameBuilder = (theme: Theme) => string;
634
+ interface ThemeDomConfig {
635
+ strategy?: ThemeDomStrategy;
636
+ rootSelector?: string;
637
+ darkThemePrefix?: string;
638
+ attributeName?: string;
639
+ themeClassPrefix?: string;
640
+ classNameBuilder?: ThemeClassNameBuilder;
641
+ }
557
642
  /**
558
643
  * Configuration options for theme management.
559
644
  * Defines the default theme and prefix for dark theme variants.
560
645
  */
561
646
  interface ThemeConfig {
647
+ /**
648
+ * Explicit list of supported themes.
649
+ * Values outside this registry are ignored and fallback to the default theme.
650
+ * @optional
651
+ */
652
+ registry?: readonly Theme[];
562
653
  /**
563
654
  * The default theme to be applied when no other theme is specified.
564
655
  * @optional
565
656
  */
566
- defaultTheme?: Themes;
657
+ defaultTheme?: Theme;
567
658
  /**
568
659
  * Prefix string used to identify and apply dark theme variants.
569
660
  * @optional
570
661
  */
571
662
  darkThemePrefix?: string;
663
+ /**
664
+ * DOM application strategy for the active theme.
665
+ * @optional
666
+ */
667
+ dom?: ThemeDomConfig;
572
668
  }
573
669
 
574
670
  /**
@@ -587,29 +683,14 @@ interface ThemeConfig {
587
683
  * const isDarkTheme = theme === themes.dark;
588
684
  * ```
589
685
  */
590
- declare const themes: Record<Themes, Themes>;
686
+ declare const themes: Record<Themes$1, Themes$1>;
591
687
  /**
592
- * CSS class prefix used for dark theme styling.
593
- *
594
- * This constant defines the prefix applied to HTML elements when the dark theme is active.
595
- * It is typically added to the root element or specific components to enable dark theme styles.
596
- *
597
- * @example
598
- * ```typescript
599
- * document.body.classList.add(darkThemePrefix); // Applies 're-dark' class
600
- * ```
688
+ * @deprecated Prefer `theme.dom.darkClassName` via `providePresentia(...)`.
601
689
  */
602
690
  declare const darkThemePrefix = "re-dark";
603
691
 
604
692
  /**
605
- * Default theme configuration object.
606
- *
607
- * Defines the initial theme settings for the application.
608
- * By default, sets the light theme as the active theme.
609
- *
610
- * This configuration can be overridden when providing `THEME_CONFIG` token
611
- * at the module or application level.
612
- * ```
693
+ * @deprecated Prefer configuring themes through `providePresentia({ theme: ... })`.
613
694
  */
614
695
  declare const defaultThemeConfig: {
615
696
  defaultTheme: _reforgium_internal.Themes;
@@ -633,6 +714,23 @@ declare const defaultThemeConfig: {
633
714
  */
634
715
  declare const THEME_CONFIG: InjectionToken<ThemeConfig>;
635
716
 
717
+ /**
718
+ * @deprecated Prefer configuring theme persistence through `providePresentia({ theme: { persistence... } })`.
719
+ */
720
+ declare const defaultThemePersistenceAdapter: StorageInterface<string, string>;
721
+ /**
722
+ * DI token for the persistence adapter used by `ThemeService`
723
+ * to store and retrieve the selected theme (default key: `'theme'`).
724
+ *
725
+ * By default `presentia` provides a `localStorage`-backed adapter.
726
+ *
727
+ * Example:
728
+ * ```ts
729
+ * { provide: THEME_PERSISTENCE_ADAPTER, useValue: sessionStorageAdapter }
730
+ * ```
731
+ */
732
+ declare const THEME_PERSISTENCE_ADAPTER: InjectionToken<PersistenceAdapter>;
733
+
636
734
  /**
637
735
  * Service for managing application theme.
638
736
  *
@@ -649,8 +747,15 @@ declare const THEME_CONFIG: InjectionToken<ThemeConfig>;
649
747
  declare class ThemeService {
650
748
  #private;
651
749
  private readonly config;
750
+ private readonly registry;
652
751
  private readonly themeDefault;
752
+ private readonly domStrategy;
653
753
  private readonly darkPrefix;
754
+ private readonly attributeName;
755
+ private readonly themeClassPrefix;
756
+ private readonly classNameBuilder;
757
+ private readonly rootSelector;
758
+ private readonly persistence;
654
759
  private readonly isBrowser;
655
760
  private readonly document;
656
761
  /**
@@ -662,12 +767,13 @@ declare class ThemeService {
662
767
  * <div [class]="themeService.theme()"></div>
663
768
  * ```
664
769
  */
665
- theme: i0.Signal<Themes>;
770
+ theme: _angular_core.Signal<Theme>;
666
771
  /**
667
772
  * Convenient flag returning `true` if the light theme is active.
668
773
  * Suitable for conditional style application or resource selection.
669
774
  */
670
- isLight: i0.Signal<boolean>;
775
+ isLight: _angular_core.Signal<boolean>;
776
+ isDark: _angular_core.Signal<boolean>;
671
777
  constructor();
672
778
  /**
673
779
  * Switches theme.
@@ -677,12 +783,25 @@ declare class ThemeService {
677
783
  *
678
784
  * @param theme — explicit theme value (`'light'` or `'dark'`).
679
785
  */
680
- switch(theme?: Themes): void;
786
+ switch(theme?: Theme): void;
787
+ is(theme: Theme | readonly Theme[]): boolean;
681
788
  private resolveTheme;
682
- static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, never>;
683
- static ɵprov: i0.ɵɵInjectableDeclaration<ThemeService>;
789
+ private resolveRegistry;
790
+ private resolveInitialTheme;
791
+ private getStoredTheme;
792
+ private persistTheme;
793
+ private applyThemeToDom;
794
+ private nextTheme;
795
+ private resolveRootElement;
796
+ private resolveThemeClassName;
797
+ private clearThemeClasses;
798
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ThemeService, never>;
799
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<ThemeService>;
684
800
  }
685
801
 
802
+ /**
803
+ * @deprecated Prefer `PresentiaConfig` with `providePresentia(...)` for the grouped v2 API.
804
+ */
686
805
  interface AppConfig {
687
806
  locale: LocaleConfig;
688
807
  theme?: ThemeConfig;
@@ -690,8 +809,77 @@ interface AppConfig {
690
809
  langPipe?: LangPipeConfig;
691
810
  langMissingKeyHandler?: LangMissingKeyHandler;
692
811
  }
812
+ /**
813
+ * @deprecated Prefer `providePresentia(...)` for new integrations.
814
+ */
693
815
  declare function provideReInit(config: AppConfig): EnvironmentProviders;
694
816
 
817
+ type PresentiaLangConfig = {
818
+ source: {
819
+ url: string;
820
+ fromAssets: boolean;
821
+ defaultLang?: Langs;
822
+ fallbackLang?: Langs;
823
+ supportedLangs?: readonly string[];
824
+ kgValue?: 'kg' | 'ky';
825
+ };
826
+ rendering?: {
827
+ placeholder?: string | ((query: string) => string);
828
+ missingValue?: string;
829
+ };
830
+ preload?: {
831
+ global?: readonly string[];
832
+ routes?: LangRouteNamespacePreloadConfig;
833
+ };
834
+ transport?: {
835
+ requestBuilder?: LangRequestBuilder;
836
+ requestOptionsFactory?: LangRequestOptionsFactory;
837
+ responseAdapter?: LangResponseAdapter;
838
+ batchRequestBuilder?: LangBatchRequestBuilder;
839
+ batchResponseAdapter?: LangBatchResponseAdapter;
840
+ maxBatchSize?: number;
841
+ };
842
+ cache?: LangNamespaceCacheConfig;
843
+ persistence?: StorageStrategy | 'none';
844
+ storage?: StorageInterface<string, string>;
845
+ /**
846
+ * @deprecated Prefer `storage`.
847
+ */
848
+ persistenceAdapter?: PersistenceAdapter;
849
+ diagnostics?: {
850
+ lateNamespaceLoads?: boolean;
851
+ };
852
+ missingKeyHandler?: LangMissingKeyHandler;
853
+ };
854
+ type PresentiaThemeConfig = {
855
+ registry?: readonly Theme[];
856
+ defaultTheme?: ThemeConfig['defaultTheme'];
857
+ persistence?: StorageStrategy | 'none';
858
+ storage?: StorageInterface<string, string>;
859
+ /**
860
+ * @deprecated Prefer `storage`.
861
+ */
862
+ persistenceAdapter?: PersistenceAdapter;
863
+ dom?: {
864
+ strategy?: 'root-class' | 'data-attribute';
865
+ rootSelector?: string;
866
+ darkClassName?: string;
867
+ attributeName?: string;
868
+ classPrefix?: string;
869
+ classNameBuilder?: (theme: Theme) => string;
870
+ };
871
+ };
872
+ type PresentiaAdaptiveConfig = {
873
+ breakpoints?: DeviceBreakpoints;
874
+ strategy?: 'width';
875
+ };
876
+ interface PresentiaConfig {
877
+ lang: PresentiaLangConfig;
878
+ theme?: PresentiaThemeConfig;
879
+ adaptive?: PresentiaAdaptiveConfig;
880
+ }
881
+ declare function providePresentia(config: PresentiaConfig): EnvironmentProviders;
882
+
695
883
  /**
696
884
  * Open Graph meta tags type definition.
697
885
  * Used for social media sharing preview configuration.
@@ -781,8 +969,8 @@ declare class SeoService {
781
969
  setJsonLd(schema: object): void;
782
970
  private upsert;
783
971
  private upsertLink;
784
- static ɵfac: i0.ɵɵFactoryDeclaration<SeoService, never>;
785
- static ɵprov: i0.ɵɵInjectableDeclaration<SeoService>;
972
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SeoService, never>;
973
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SeoService>;
786
974
  }
787
975
 
788
976
  /**
@@ -806,7 +994,6 @@ declare class SeoService {
806
994
  declare class SeoRouteListener {
807
995
  private router;
808
996
  private seo;
809
- private ar;
810
997
  private destroyRef;
811
998
  private initialized;
812
999
  private baseUrl;
@@ -818,60 +1005,77 @@ declare class SeoRouteListener {
818
1005
  * Trailing slashes will be removed automatically.
819
1006
  */
820
1007
  init(baseUrl: string): void;
821
- /**
822
- * Recursively finds the deepest (most nested) activated route in the route tree.
823
- * This is used to extract route data from the currently active leaf route.
824
- *
825
- * @param r - The root activated route to start traversing from.
826
- * @returns The deepest child route in the hierarchy.
827
- */
828
- private deepest;
829
- static ɵfac: i0.ɵɵFactoryDeclaration<SeoRouteListener, never>;
830
- static ɵprov: i0.ɵɵInjectableDeclaration<SeoRouteListener>;
1008
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SeoRouteListener, never>;
1009
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SeoRouteListener>;
831
1010
  }
832
1011
 
1012
+ type RouteWatcherReadStrategy = 'deepest' | 'merged';
1013
+
1014
+ type RouteWatcherState = {
1015
+ params: Record<string, string>;
1016
+ deepestParams: Record<string, string>;
1017
+ query: Record<string, string>;
1018
+ data: Record<string, unknown>;
1019
+ mergedData: Record<string, unknown>;
1020
+ url: string;
1021
+ routePattern: string;
1022
+ fragment: string | null;
1023
+ };
833
1024
  /**
834
1025
  * Reactive snapshot of the current route (the deepest active route).
835
1026
  * Updates on every `NavigationEnd` event.
836
- *
837
- * Provides:
838
- * - `params` / `query` — strings (as in Angular Router)
839
- * - `data` — arbitrary data (from route configuration/resolvers)
840
- * - `url` — string assembled from `UrlSegment[]`
841
- * - `fragment` — hash (#section)
842
- * - `selectData(key)` — type-safe selector for `data`
843
- * - `state` — combined computed object (convenient for single subscriber)
844
1027
  */
845
1028
  declare class RouteWatcher {
846
1029
  #private;
847
1030
  private readonly router;
848
1031
  private readonly destroyRef;
849
- /** Signal for tracking and retrieving URL parameters */
850
- readonly params: i0.Signal<Record<string, string>>;
851
- /** Signal for tracking and retrieving query parameters */
852
- readonly query: i0.Signal<Record<string, string>>;
853
- /** Signal for tracking and retrieving route data */
854
- readonly data: i0.Signal<Record<string, unknown>>;
855
- /** Signal for tracking and retrieving URL */
856
- readonly url: i0.Signal<string>;
857
- /** Signal for tracking and retrieving URL fragment */
858
- readonly fragment: i0.Signal<string | null>;
859
- /** Combined computed snapshot (to avoid multiple effects) */
860
- readonly state: i0.Signal<{
861
- params: Record<string, string>;
862
- query: Record<string, string>;
863
- data: Record<string, unknown>;
864
- url: string;
865
- fragment: string | null;
866
- }>;
1032
+ /** Params merged from root to deepest route. */
1033
+ readonly params: _angular_core.Signal<Record<string, string>>;
1034
+ /** Params declared on the deepest route only. */
1035
+ readonly deepestParams: _angular_core.Signal<Record<string, string>>;
1036
+ /** Query params from the current navigation. */
1037
+ readonly query: _angular_core.Signal<Record<string, string>>;
1038
+ /** Deepest route data only. */
1039
+ readonly data: _angular_core.Signal<Record<string, unknown>>;
1040
+ /** Route data merged from root to deepest route. */
1041
+ readonly mergedData: _angular_core.Signal<Record<string, unknown>>;
1042
+ /** Full current url path assembled from root to deepest route. */
1043
+ readonly url: _angular_core.Signal<string>;
1044
+ /** Current route config pattern, e.g. `orgs/:orgId/users/:id`. */
1045
+ readonly routePattern: _angular_core.Signal<string>;
1046
+ /** Current url fragment without `#`. */
1047
+ readonly fragment: _angular_core.Signal<string | null>;
1048
+ /** Combined computed snapshot. */
1049
+ readonly state: _angular_core.Signal<RouteWatcherState>;
867
1050
  constructor();
868
- /** Convenient selector for a data key with type-safe casting */
869
- selectData<T = unknown>(key: string): i0.Signal<T | undefined>;
1051
+ selectData<T = unknown>(key: string, strategy?: RouteWatcherReadStrategy): _angular_core.Signal<T | undefined>;
1052
+ selectParam(key: string, strategy?: RouteWatcherReadStrategy): _angular_core.Signal<string | undefined>;
1053
+ matchesPath(path: string | RegExp): boolean;
870
1054
  private deepestSnapshot;
871
- static ɵfac: i0.ɵɵFactoryDeclaration<RouteWatcher, never>;
872
- static ɵprov: i0.ɵɵInjectableDeclaration<RouteWatcher>;
1055
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RouteWatcher, never>;
1056
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<RouteWatcher>;
1057
+ }
1058
+
1059
+ declare const PRESENTIA_ROUTE_NAMESPACES_DATA_KEY = "presentiaNamespaces";
1060
+ declare function providePresentiaRouteNamespacePreload(): _angular_core.EnvironmentProviders;
1061
+
1062
+ /**
1063
+ * @deprecated Diagnostics are usually enabled through route preload config, not by consuming this service directly.
1064
+ */
1065
+ declare class RouteNamespaceDiagnosticsService {
1066
+ private readonly router;
1067
+ private readonly enabled;
1068
+ private readonly warned;
1069
+ private currentUrl;
1070
+ private currentNamespaces;
1071
+ private navigationSettled;
1072
+ constructor();
1073
+ registerRouteNamespaces(url: string, namespaces: readonly string[]): void;
1074
+ warnLateNamespaceLoad(namespace: string): void;
1075
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RouteNamespaceDiagnosticsService, never>;
1076
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<RouteNamespaceDiagnosticsService>;
873
1077
  }
874
1078
 
875
- export { AdaptiveService, DEVICE_BREAKPOINTS, IfDeviceDirective, LANG_CONFIG, LANG_MISSING_KEY_HANDLER, LANG_PIPE_CONFIG, LangDirective, LangPipe, LangService, RouteWatcher, SeoRouteListener, SeoService, THEME_CONFIG, ThemeService, darkThemePrefix, defaultBreakpoints, defaultThemeConfig, innerLangVal, provideReInit, themes };
876
- export type { AppConfig, DeviceBreakpoints, LangBatchRequestBuilder, LangBatchRequestContext, LangBatchResponseAdapter, LangBatchResponseContext, LangDirectiveConfig, LangDirectiveMode, LangDto, LangHttpRequestOptions, LangKey, LangKeyRegistry, LangMissingKeyHandler, LangModel, LangNamespaceCacheConfig, LangParamValue, LangParams, LangPipeConfig, LangRequestBuilder, LangRequestContext, LangRequestOptionsFactory, LangResponseAdapter, LangResponseContext, LocaleConfig, OgType, ThemeConfig, TwitterCardType };
1079
+ export { AdaptiveService, DEVICE_BREAKPOINTS, IfDeviceDirective, LANG_CONFIG, LANG_MISSING_KEY_HANDLER, LANG_PERSISTENCE_ADAPTER, LANG_PIPE_CONFIG, LangDirective, LangPipe, LangService, PRESENTIA_ROUTE_NAMESPACES_DATA_KEY, RouteNamespaceDiagnosticsService, RouteWatcher, SeoRouteListener, SeoService, THEME_CONFIG, THEME_PERSISTENCE_ADAPTER, ThemeService, darkThemePrefix, defaultBreakpoints, defaultLangPersistenceAdapter, defaultThemeConfig, defaultThemePersistenceAdapter, innerLangVal, providePresentia, providePresentiaRouteNamespacePreload, provideReInit, themes };
1080
+ export type { AppConfig, BaseTheme, DeviceBreakpoints, LangBatchRequestBuilder, LangBatchRequestContext, LangBatchResponseAdapter, LangBatchResponseContext, LangDirectiveConfig, LangDirectiveMode, LangDto, LangHttpRequestOptions, LangKey, LangKeyRegistry, LangMissingKeyHandler, LangModel, LangNamespaceCacheConfig, LangParamValue, LangParams, LangPipeConfig, LangRequestBuilder, LangRequestContext, LangRequestOptionsFactory, LangResponseAdapter, LangResponseContext, LangRouteNamespaceManifest, LangRouteNamespacePreloadConfig, LangRouteNamespacePreloadMergeStrategy, LangRouteNamespacePreloadMode, LoadNamespaceError, LocaleConfig, OgType, PersistenceAdapter, PresentiaAdaptiveConfig, PresentiaConfig, PresentiaLangConfig, PresentiaThemeConfig, RouteWatcherReadStrategy, RouteWatcherState, Theme, ThemeConfig, Themes, TwitterCardType };
877
1081
  //# sourceMappingURL=reforgium-presentia.d.ts.map