@ng-forge/dynamic-forms 0.6.0 → 0.7.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.
@@ -1,9 +1,9 @@
1
1
  import * as rxjs from 'rxjs';
2
2
  import { Observable } from 'rxjs';
3
3
  import * as _angular_core from '@angular/core';
4
- import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, Provider, EnvironmentProviders, PipeTransform } from '@angular/core';
4
+ import { Signal, Injector, WritableSignal, InjectionToken, Type, ResourceRef, EnvironmentInjector, Provider, EnvironmentProviders, Resource, PipeTransform } from '@angular/core';
5
5
  import * as _angular_forms_signals from '@angular/forms/signals';
6
- import { FieldTree, FieldContext, ValidationError as ValidationError$1, TreeValidationResult, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
6
+ import { FieldTree, FieldContext, TreeValidationResult, ValidationError as ValidationError$1, SchemaPath, SchemaPathTree } from '@angular/forms/signals';
7
7
  import * as _angular_forms from '@angular/forms';
8
8
  import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
9
9
  import { FormSchema } from '@ng-forge/dynamic-forms/schema';
@@ -379,6 +379,14 @@ type MapperFn<T extends FieldDef<unknown>> = (input: T) => Signal<Record<string,
379
379
  * - 'flatten': Field's children are flattened to parent level (for container fields)
380
380
  */
381
381
  type ValueHandlingMode = 'include' | 'exclude' | 'flatten';
382
+ /**
383
+ * Semantic grouping of interchangeable field UI alternatives.
384
+ *
385
+ * Used by tooling (e.g., openapi-generator) to discover which field types
386
+ * can substitute for each other. A field with scope 'boolean' means it's
387
+ * one of several ways to render a boolean value (checkbox, toggle, etc.).
388
+ */
389
+ type FieldScope = 'boolean' | 'single-select' | 'multi-select' | 'text-input' | 'numeric' | 'date';
382
390
  /**
383
391
  * Configuration interface for registering custom field types.
384
392
  *
@@ -444,6 +452,8 @@ interface FieldTypeDefinition<T extends FieldDef<any> = any> {
444
452
  * ```
445
453
  */
446
454
  propsToMeta?: string[];
455
+ /** Semantic scope for tooling to discover interchangeable field alternatives */
456
+ scope?: FieldScope | FieldScope[];
447
457
  }
448
458
  /**
449
459
  * Injection token for the global field type registry.
@@ -533,56 +543,17 @@ interface FieldValueCondition {
533
543
  value?: unknown;
534
544
  }
535
545
  /**
536
- * Condition that compares the entire form value against an expected value.
537
- *
538
- * @deprecated Use `FieldValueCondition` for specific field checks, or
539
- * `JavascriptCondition` with an expression for complex form-level comparisons.
540
- * Will be removed in a future minor version.
541
- *
542
- * @public
543
- */
544
- interface FormValueCondition {
545
- type: 'formValue';
546
- /** Comparison operator */
547
- operator: ComparisonOperator;
548
- /** Value to compare against */
549
- value?: unknown;
550
- }
551
- /**
552
- * Condition that invokes a registered custom function by name (new API).
546
+ * Condition that invokes a registered custom function by name.
553
547
  *
554
548
  * Register functions via `customFnConfig.customFunctions`.
555
549
  *
556
- * @internal
550
+ * @public
557
551
  */
558
- interface CustomConditionNew {
552
+ interface CustomCondition {
559
553
  type: 'custom';
560
554
  /** Name of the registered custom function to invoke */
561
555
  functionName: string;
562
556
  }
563
- /**
564
- * @deprecated Use `CustomCondition` with `functionName` instead.
565
- * The `expression` field was misnamed — it holds a function registry key, not a JS expression.
566
- * Will be removed in a future minor version.
567
- *
568
- * @internal
569
- */
570
- interface CustomConditionDeprecated {
571
- type: 'custom';
572
- /**
573
- * @deprecated Use `functionName` instead. Will be removed in a future minor version.
574
- */
575
- expression: string;
576
- }
577
- /**
578
- * Condition that invokes a registered custom function by name.
579
- *
580
- * Use `functionName` (new API). The `expression` field is deprecated.
581
- * Register functions via `customFnConfig.customFunctions`.
582
- *
583
- * @public
584
- */
585
- type CustomCondition = CustomConditionNew | CustomConditionDeprecated;
586
557
  /**
587
558
  * Condition that evaluates a JavaScript expression using the secure AST-based parser.
588
559
  *
@@ -697,7 +668,7 @@ interface OrCondition {
697
668
  *
698
669
  * @public
699
670
  */
700
- type ConditionalExpression = FieldValueCondition | FormValueCondition | CustomCondition | JavascriptCondition | HttpCondition | AsyncCondition | AndCondition | OrCondition;
671
+ type ConditionalExpression = FieldValueCondition | CustomCondition | JavascriptCondition | HttpCondition | AsyncCondition | AndCondition | OrCondition;
701
672
 
702
673
  /**
703
674
  * Logic configuration for container fields (page, group, row, array).
@@ -1772,161 +1743,15 @@ type DebouncedFunctionDerivationLogicConfig = FunctionDerivationBase & Debounced
1772
1743
  * @public
1773
1744
  */
1774
1745
  type DerivationLogicConfig = OnChangeHttpDerivationLogicConfig | DebouncedHttpDerivationLogicConfig | OnChangeAsyncFunctionDerivationLogicConfig | DebouncedAsyncFunctionDerivationLogicConfig | OnChangeExpressionDerivationLogicConfig | DebouncedExpressionDerivationLogicConfig | OnChangeValueDerivationLogicConfig | DebouncedValueDerivationLogicConfig | OnChangeFunctionDerivationLogicConfig | DebouncedFunctionDerivationLogicConfig;
1775
- /**
1776
- * Base configuration for property derivation logic.
1777
- *
1778
- * Property derivations compute values for field properties (like `minDate`, `options`,
1779
- * `label`, `placeholder`) based on form values and external data. Unlike value derivations
1780
- * which set the field's value, property derivations update component input properties.
1781
- *
1782
- * All property derivations are self-targeting: the logic is placed on the field whose
1783
- * property should be derived.
1784
- *
1785
- * @internal
1786
- */
1787
- interface BasePropertyDerivationLogicConfig {
1788
- /**
1789
- * Logic type identifier for property derivation.
1790
- */
1791
- type: 'propertyDerivation';
1792
- /**
1793
- * The target property to set on the field component.
1794
- *
1795
- * **Depth limit (max 2 levels):** Only simple and single-dot-nested paths are
1796
- * supported. Paths with 2+ dots (e.g., `'a.b.c'`) will throw a `DynamicFormError`
1797
- * at runtime. This is an architectural constraint of the override merging strategy.
1798
- *
1799
- * Supported formats:
1800
- * - Simple: `'minDate'`, `'options'`, `'label'`, `'placeholder'`
1801
- * - Nested (1 dot): `'props.appearance'`, `'meta.autocomplete'`
1802
- *
1803
- * **Note:** There is no compile-time validation that the property name matches
1804
- * an actual input on the field component. Typos will silently write to the
1805
- * override store with no visible effect. A dev-mode warning is emitted when
1806
- * the override key doesn't match any existing input property.
1807
- *
1808
- * @example
1809
- * ```typescript
1810
- * targetProperty: 'minDate' // ✅ Simple property
1811
- * targetProperty: 'options' // ✅ Simple property
1812
- * targetProperty: 'props.appearance' // ✅ Single-nested property
1813
- * targetProperty: 'a.b.c' // ❌ Throws DynamicFormError (too deep)
1814
- * ```
1815
- */
1816
- targetProperty: string;
1817
- /**
1818
- * Optional name for this derivation for debugging purposes.
1819
- *
1820
- * When provided, this name appears in property derivation debug logs.
1821
- */
1822
- debugName?: string;
1823
- /**
1824
- * Condition that determines when this property derivation applies.
1825
- *
1826
- * Defaults to `true` (always apply).
1827
- *
1828
- * Note: FormStateCondition is not supported for property derivations.
1829
- */
1830
- condition?: ConditionalExpression | boolean;
1831
- /**
1832
- * Static value to set on the target property.
1833
- *
1834
- * Mutually exclusive with `expression` and `functionName`.
1835
- */
1836
- value?: unknown;
1837
- /**
1838
- * JavaScript expression to evaluate for the derived property value.
1839
- *
1840
- * Has access to `formValue` object containing all form values.
1841
- * For array fields, `formValue` is scoped to the current array item.
1842
- *
1843
- * Mutually exclusive with `value` and `functionName`.
1844
- *
1845
- * @example
1846
- * ```typescript
1847
- * expression: 'formValue.startDate'
1848
- * expression: 'formValue.quantity > 10 ? "bulk" : "standard"'
1849
- * ```
1850
- */
1851
- expression?: string;
1852
- /**
1853
- * Name of a registered custom property derivation function.
1854
- *
1855
- * Register functions in `customFnConfig.propertyDerivations`.
1856
- * Mutually exclusive with `value` and `expression`.
1857
- */
1858
- functionName?: string;
1859
- /**
1860
- * Explicit field dependencies for property derivations.
1861
- *
1862
- * When using `functionName`, you can optionally specify which fields
1863
- * the function depends on. If not provided with `functionName`, defaults
1864
- * to all fields ('*').
1865
- * For `expression`, dependencies are automatically extracted.
1866
- * For `value`, no dependencies are needed (static value).
1867
- */
1868
- dependsOn?: string[];
1869
- }
1870
- /**
1871
- * Property derivation that evaluates immediately on change (default).
1872
- *
1873
- * @internal
1874
- */
1875
- interface OnChangePropertyDerivationLogicConfig extends BasePropertyDerivationLogicConfig {
1876
- /**
1877
- * Trigger for immediate evaluation.
1878
- * @default 'onChange'
1879
- */
1880
- trigger?: 'onChange';
1881
- /** Not allowed for onChange trigger */
1882
- debounceMs?: never;
1883
- }
1884
- /**
1885
- * Property derivation that evaluates after a debounce period.
1886
- *
1887
- * @internal
1888
- */
1889
- interface DebouncedPropertyDerivationLogicConfig extends BasePropertyDerivationLogicConfig {
1890
- /**
1891
- * Trigger for debounced evaluation.
1892
- */
1893
- trigger: 'debounced';
1894
- /**
1895
- * Debounce duration in milliseconds.
1896
- * @default 500
1897
- */
1898
- debounceMs?: number;
1899
- }
1900
- /**
1901
- * Configuration for property derivation logic.
1902
- *
1903
- * @deprecated Use `DerivationLogicConfig` with `targetProperty` instead.
1904
- * The unified `type: 'derivation'` with `targetProperty` provides the same
1905
- * functionality with a simpler API surface.
1906
- *
1907
- * ```typescript
1908
- * // Before (deprecated)
1909
- * { type: 'propertyDerivation', targetProperty: 'minDate', expression: '...' }
1910
- *
1911
- * // After (preferred)
1912
- * { type: 'derivation', targetProperty: 'minDate', expression: '...' }
1913
- * ```
1914
- *
1915
- * Will be removed in a future minor version.
1916
- *
1917
- * @public
1918
- */
1919
- type PropertyDerivationLogicConfig = OnChangePropertyDerivationLogicConfig | DebouncedPropertyDerivationLogicConfig;
1920
1746
  /**
1921
1747
  * Union type for all logic configurations.
1922
1748
  *
1923
1749
  * - `StateLogicConfig`: For field state changes (hidden, readonly, disabled, required)
1924
- * - `DerivationLogicConfig`: For value derivation
1925
- * - `PropertyDerivationLogicConfig`: For property derivation
1750
+ * - `DerivationLogicConfig`: For value derivation (including property derivation via `targetProperty`)
1926
1751
  *
1927
1752
  * @public
1928
1753
  */
1929
- type LogicConfig = StateLogicConfig | DerivationLogicConfig | PropertyDerivationLogicConfig;
1754
+ type LogicConfig = StateLogicConfig | DerivationLogicConfig;
1930
1755
  /**
1931
1756
  * Log level for derivation debug output.
1932
1757
  *
@@ -1946,18 +1771,6 @@ type DerivationLogLevel = 'none' | 'summary' | 'verbose';
1946
1771
  * @public
1947
1772
  */
1948
1773
  declare function isFormStateCondition(condition: StateLogicConfig['condition'] | DerivationLogicConfig['condition']): condition is FormStateCondition;
1949
- /**
1950
- * Type guard to check if a logic config is a PropertyDerivationLogicConfig.
1951
- *
1952
- * @deprecated Use `isDerivationLogicConfig(config) && hasTargetProperty(config)` instead.
1953
- * Will be removed in a future minor version.
1954
- *
1955
- * @param config - The logic config to check
1956
- * @returns true if the config is for property derivation
1957
- *
1958
- * @public
1959
- */
1960
- declare function isPropertyDerivationLogicConfig(config: LogicConfig): config is PropertyDerivationLogicConfig;
1961
1774
 
1962
1775
  /**
1963
1776
  * Interface for dynamic forms logger implementations.
@@ -2362,19 +2175,36 @@ type MaybeOptional<T, V> = T extends {
2362
2175
  } ? V : T extends {
2363
2176
  required: true;
2364
2177
  } ? V : V | undefined;
2178
+ /**
2179
+ * Infers the value type from a single template field (for primitive arrays).
2180
+ * Mirrors InferValueType logic: slider → number, input[number] → number, else string.
2181
+ */
2182
+ type InferSingleTemplateValue<T, D extends number> = T extends {
2183
+ type: 'slider';
2184
+ } ? number : T extends {
2185
+ type: 'input';
2186
+ props: {
2187
+ type: 'number';
2188
+ };
2189
+ } ? number : T extends {
2190
+ type: 'checkbox' | 'toggle';
2191
+ } ? boolean : T extends {
2192
+ value: infer V;
2193
+ } ? Widen<V, Depth[D]> : string;
2365
2194
  /**
2366
2195
  * Infers the value type for an array field.
2367
- * Handles three cases:
2196
+ * Handles four cases:
2368
2197
  * 1. Simplified array with template + value → infer item type from value
2369
- * 2. Simplified array with template only → unknown[]
2370
- * 3. Full-API array with fields → infer from children
2198
+ * 2. Simplified array with array template (no value) → infer object type from template fields
2199
+ * 3. Simplified array with single-field template (no value) → infer primitive type from template field
2200
+ * 4. Full-API array with fields → infer from children
2371
2201
  */
2372
2202
  type InferArrayValue<T, D extends number> = T extends {
2373
2203
  template: unknown;
2374
2204
  value: readonly (infer Item)[];
2375
2205
  } ? Widen<Item>[] : T extends {
2376
- template: unknown;
2377
- } ? unknown[] : T extends {
2206
+ template: infer TArr;
2207
+ } ? TArr extends readonly RegisteredFieldTypes[] ? InferFormValueWithDepth<[...TArr], Depth[D]>[] : InferSingleTemplateValue<TArr, D>[] : T extends {
2378
2208
  fields: infer F;
2379
2209
  } ? F extends RegisteredFieldTypes[] ? InferFormValueWithDepth<F, Depth[D]>[] : unknown[] : unknown[];
2380
2210
  /**
@@ -2457,11 +2287,11 @@ type InferFormValue$1<T> = ExtractFields<T> extends readonly RegisteredFieldType
2457
2287
  */
2458
2288
  interface HttpValidationResponseMapping {
2459
2289
  /**
2460
- * Expression evaluated with scope `{ response }`. Truthy = valid (no error).
2290
+ * Expression evaluated with scope `{ response }`. Must evaluate to `true` (strict boolean) to be valid.
2461
2291
  *
2462
2292
  * NOTE: This is the OPPOSITE of the function-based HttpCustomValidator.onSuccess
2463
2293
  * convention, which maps successful HTTP responses to validation errors.
2464
- * Here, truthy means "validation passed".
2294
+ * Here, `=== true` means "validation passed". Non-boolean results are treated as invalid and trigger a warning.
2465
2295
  */
2466
2296
  validWhen: string;
2467
2297
  /** Error kind returned when validation fails — maps to field-level `validationMessages` */
@@ -2527,16 +2357,10 @@ interface CustomValidatorConfig extends BaseValidatorConfig {
2527
2357
  * Async custom validator configuration using Angular's validateAsync API.
2528
2358
  * Returns Observable<ValidationError | ValidationError[] | null>.
2529
2359
  *
2530
- * Accepts both `'async'` (preferred) and `'customAsync'` (deprecated) type literals.
2531
2360
  */
2532
2361
  interface AsyncValidatorConfig extends BaseValidatorConfig {
2533
- /**
2534
- * Validator type identifier.
2535
- *
2536
- * Use `'async'` for new code. `'customAsync'` is accepted for backward compatibility
2537
- * but emits a deprecation warning in dev mode.
2538
- */
2539
- type: 'async' | 'customAsync';
2362
+ /** Validator type identifier. */
2363
+ type: 'async';
2540
2364
  /** Name of registered async validator function */
2541
2365
  functionName: string;
2542
2366
  /** Optional parameters to pass to validator function */
@@ -2550,28 +2374,15 @@ interface AsyncValidatorConfig extends BaseValidatorConfig {
2550
2374
  *
2551
2375
  * Discriminated from `DeclarativeHttpValidatorConfig` by the presence of `functionName`.
2552
2376
  *
2553
- * Accepts both `'http'` (preferred) and `'customHttp'` (deprecated) type literals.
2554
- *
2555
- * @deprecated Prefer `DeclarativeHttpValidatorConfig` (`type: 'http'` with `http` + `responseMapping`)
2556
- * for fully JSON-serializable validation. Use this form only when function registration is required.
2557
2377
  */
2558
2378
  interface FunctionHttpValidatorConfig extends BaseValidatorConfig {
2559
- /**
2560
- * Validator type identifier.
2561
- *
2562
- * Use `'http'` for new code. `'customHttp'` is accepted for backward compatibility
2563
- * but emits a deprecation warning in dev mode.
2564
- */
2565
- type: 'http' | 'customHttp';
2379
+ /** Validator type identifier. */
2380
+ type: 'http';
2566
2381
  /** Name of registered HTTP validator configuration */
2567
2382
  functionName: string;
2568
2383
  /** Optional parameters to pass to HTTP validator */
2569
2384
  params?: Record<string, unknown>;
2570
2385
  }
2571
- /**
2572
- * @deprecated Use `FunctionHttpValidatorConfig` instead. Will be removed in a future minor version.
2573
- */
2574
- type HttpValidatorConfig = FunctionHttpValidatorConfig;
2575
2386
  /**
2576
2387
  * Declarative HTTP validator configuration — fully JSON-serializable, no function registration required.
2577
2388
  *
@@ -2963,7 +2774,7 @@ type FormFieldStateMap = Record<string, FieldStateInfo | undefined>;
2963
2774
  */
2964
2775
  type FieldStateContext = FieldStateInfo;
2965
2776
 
2966
- interface EvaluationContext<TValue = unknown> {
2777
+ interface EvaluationContext<TValue = unknown, TFormValue extends Record<string, unknown> = any> {
2967
2778
  /** Current field value */
2968
2779
  fieldValue: TValue;
2969
2780
  /**
@@ -2973,7 +2784,7 @@ interface EvaluationContext<TValue = unknown> {
2973
2784
  * For array item derivations, this is scoped to the current array item.
2974
2785
  * Use `rootFormValue` to access the complete form when inside an array context.
2975
2786
  */
2976
- formValue: Record<string, unknown>;
2787
+ formValue: TFormValue;
2977
2788
  /** Field path for relative references */
2978
2789
  fieldPath: string;
2979
2790
  /** Custom evaluation functions */
@@ -3114,7 +2925,7 @@ interface EvaluationContext<TValue = unknown> {
3114
2925
  * };
3115
2926
  * ```
3116
2927
  */
3117
- type CustomFunction = (context: EvaluationContext) => unknown;
2928
+ type CustomFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => unknown;
3118
2929
 
3119
2930
  /**
3120
2931
  * Async function for derivations — returns any value.
@@ -3133,7 +2944,7 @@ type CustomFunction = (context: EvaluationContext) => unknown;
3133
2944
  *
3134
2945
  * @public
3135
2946
  */
3136
- type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown> | Observable<unknown>;
2947
+ type AsyncDerivationFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<unknown> | Observable<unknown>;
3137
2948
  /**
3138
2949
  * Async function for conditions — returns boolean.
3139
2950
  *
@@ -3151,7 +2962,7 @@ type AsyncDerivationFunction = (context: EvaluationContext) => Promise<unknown>
3151
2962
  *
3152
2963
  * @public
3153
2964
  */
3154
- type AsyncConditionFunction = (context: EvaluationContext) => Promise<boolean> | Observable<boolean>;
2965
+ type AsyncConditionFunction<TFormValue extends Record<string, unknown> = any> = (context: EvaluationContext<unknown, TFormValue>) => Promise<boolean> | Observable<boolean>;
3155
2966
 
3156
2967
  /**
3157
2968
  * Re-export Angular's ValidationError for consistency
@@ -3416,7 +3227,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
3416
3227
  /**
3417
3228
  * Signal forms adapter configuration.
3418
3229
  */
3419
- customFnConfig?: CustomFnConfig;
3230
+ customFnConfig?: CustomFnConfig<TValue extends Record<string, unknown> ? TValue : Record<string, unknown>>;
3420
3231
  /**
3421
3232
  * Form submission configuration.
3422
3233
  *
@@ -3571,7 +3382,7 @@ interface FormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = Reg
3571
3382
  *
3572
3383
  * @public
3573
3384
  */
3574
- interface CustomFnConfig {
3385
+ interface CustomFnConfig<TFormValue extends Record<string, unknown> = Record<string, unknown>> {
3575
3386
  /**
3576
3387
  * Custom evaluation functions for conditional expressions.
3577
3388
  *
@@ -3589,7 +3400,7 @@ interface CustomFnConfig {
3589
3400
  * }
3590
3401
  * ```
3591
3402
  */
3592
- customFunctions?: Record<string, CustomFunction>;
3403
+ customFunctions?: Record<string, CustomFunction<TFormValue>>;
3593
3404
  /**
3594
3405
  * Custom derivation functions for value derivation logic.
3595
3406
  *
@@ -3657,50 +3468,7 @@ interface CustomFnConfig {
3657
3468
  * }
3658
3469
  * ```
3659
3470
  */
3660
- derivations?: Record<string, CustomFunction>;
3661
- /**
3662
- * @deprecated Register functions under `derivations` instead. Use `type: 'derivation'`
3663
- * with `targetProperty` in field logic configs. Will be removed in a future minor version.
3664
- *
3665
- * Custom property derivation functions for reactive property updates.
3666
- *
3667
- * These functions compute derived values for field properties (like `minDate`,
3668
- * `options`, `label`, `placeholder`) and are called when a
3669
- * `PropertyDerivationLogicConfig` references them by `functionName`.
3670
- *
3671
- * Property derivation functions:
3672
- * - Receive an `EvaluationContext` with access to `formValue`
3673
- * - Return the value to set on the target property
3674
- * - Are called reactively when dependencies change
3675
- *
3676
- * @example
3677
- * ```typescript
3678
- * propertyDerivations: {
3679
- * getCitiesForCountry: (context) => {
3680
- * const countryCities: Record<string, Array<{ label: string; value: string }>> = {
3681
- * 'USA': [{ label: 'New York', value: 'ny' }, { label: 'LA', value: 'la' }],
3682
- * 'Germany': [{ label: 'Berlin', value: 'berlin' }, { label: 'Munich', value: 'munich' }],
3683
- * };
3684
- * return countryCities[context.formValue.country as string] ?? [];
3685
- * },
3686
- * }
3687
- * ```
3688
- *
3689
- * Field configuration using a property derivation function:
3690
- * ```typescript
3691
- * {
3692
- * key: 'city',
3693
- * type: 'select',
3694
- * logic: [{
3695
- * type: 'propertyDerivation',
3696
- * targetProperty: 'options',
3697
- * functionName: 'getCitiesForCountry',
3698
- * dependsOn: ['country']
3699
- * }]
3700
- * }
3701
- * ```
3702
- */
3703
- propertyDerivations?: Record<string, CustomFunction>;
3471
+ derivations?: Record<string, CustomFunction<TFormValue>>;
3704
3472
  /**
3705
3473
  * Async derivation functions for asynchronous value derivation logic.
3706
3474
  *
@@ -3730,7 +3498,7 @@ interface CustomFnConfig {
3730
3498
  * }
3731
3499
  * ```
3732
3500
  */
3733
- asyncDerivations?: Record<string, AsyncDerivationFunction>;
3501
+ asyncDerivations?: Record<string, AsyncDerivationFunction<TFormValue>>;
3734
3502
  /**
3735
3503
  * Async condition functions for asynchronous field state logic.
3736
3504
  *
@@ -3754,7 +3522,7 @@ interface CustomFnConfig {
3754
3522
  * }
3755
3523
  * ```
3756
3524
  */
3757
- asyncConditions?: Record<string, AsyncConditionFunction>;
3525
+ asyncConditions?: Record<string, AsyncConditionFunction<TFormValue>>;
3758
3526
  /**
3759
3527
  * Custom validators using Angular's public FieldContext API
3760
3528
  *
@@ -3872,72 +3640,18 @@ interface CustomFnConfig {
3872
3640
  */
3873
3641
  asyncValidators?: Record<string, AsyncCustomValidator>;
3874
3642
  /**
3875
- * @deprecated Prefer declarative HTTP validators using `type: 'http'` with `http` + `responseMapping`
3876
- * in the validators array. Function-based HTTP validators now also use `type: 'http'` with `functionName`.
3877
- * Will be removed in a future minor version.
3878
- *
3879
- * HTTP validators using Angular's validateHttp() API
3880
- *
3881
- * Angular's validateHttp provides HTTP validation with automatic request
3882
- * cancellation and integration with the resource API.
3883
- *
3884
- * **Structure:**
3885
- * - `request`: Function that returns URL string or HttpResourceRequest
3886
- * - `onSuccess`: REQUIRED - Maps HTTP response to validation errors (inverted logic!)
3887
- * - `onError`: Optional handler for HTTP errors
3888
- *
3889
- * **Benefits:**
3890
- * - Automatic request cancellation when field value changes
3891
- * - Built-in integration with Angular's resource management
3892
- * - Simpler than asyncValidators for HTTP use cases
3643
+ * HTTP validators using Angular's validateHttp() API.
3893
3644
  *
3894
- * **Important:** `onSuccess` uses inverted logic - it maps SUCCESSFUL HTTP responses
3895
- * to validation errors. For example, if the API returns `{ available: false }`,
3896
- * your `onSuccess` should return `{ kind: 'usernameTaken' }`.
3645
+ * For function-based HTTP validation with automatic request cancellation.
3646
+ * Prefer declarative HTTP validators (`type: 'http'` with `http` + `responseMapping`)
3647
+ * for fully JSON-serializable validation when possible.
3897
3648
  *
3898
- * @example Username Availability Check (GET)
3649
+ * @example
3899
3650
  * ```typescript
3900
3651
  * httpValidators: {
3901
3652
  * checkUsername: {
3902
- * request: (ctx) => {
3903
- * const username = ctx.value();
3904
- * if (!username) return undefined; // Skip validation if empty
3905
- * return `/api/users/check-username?username=${encodeURIComponent(username)}`;
3906
- * },
3907
- * onSuccess: (response, ctx) => {
3908
- * // Inverted logic: successful response may indicate validation failure
3909
- * return response.available ? null : { kind: 'usernameTaken' };
3910
- * },
3911
- * onError: (error, ctx) => {
3912
- * console.error('Availability check failed:', error);
3913
- * return null; // Don't block form on network errors
3914
- * }
3915
- * }
3916
- * }
3917
- * ```
3918
- *
3919
- * @example Address Validation (POST with Body)
3920
- * ```typescript
3921
- * httpValidators: {
3922
- * validateAddress: {
3923
- * request: (ctx) => {
3924
- * const zipCode = ctx.value();
3925
- * if (!zipCode) return undefined;
3926
- *
3927
- * return {
3928
- * url: '/api/validate-address',
3929
- * method: 'POST',
3930
- * body: {
3931
- * street: ctx.valueOf('street' as any),
3932
- * city: ctx.valueOf('city' as any),
3933
- * zipCode: zipCode
3934
- * },
3935
- * headers: { 'Content-Type': 'application/json' }
3936
- * };
3937
- * },
3938
- * onSuccess: (response) => {
3939
- * return response.valid ? null : { kind: 'invalidAddress' };
3940
- * }
3653
+ * request: (ctx) => `/api/users/check?username=${encodeURIComponent(ctx.value())}`,
3654
+ * onSuccess: (response) => response.available ? null : { kind: 'usernameTaken' },
3941
3655
  * }
3942
3656
  * }
3943
3657
  * ```
@@ -4322,17 +4036,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4322
4036
  value: _angular_core.ModelSignal<Partial<TModel> | undefined>;
4323
4037
  private destroyRef;
4324
4038
  private injector;
4039
+ protected environmentInjector: EnvironmentInjector;
4325
4040
  private eventBus;
4326
4041
  private logger;
4327
- /**
4328
- * Connect input signals to the shared deps holder BEFORE injecting FormStateManager.
4329
- * Field initializers run in declaration order, so this runs after inputs are created
4330
- * but before stateManager is injected. FormStateManager reads from these signals
4331
- * in computeds/effects, which are all lazy and evaluated after construction.
4332
- */
4333
- private readonly _connectStateDeps;
4334
- /** State manager that owns all form state. */
4335
- private stateManager;
4042
+ private dispatcher;
4043
+ /** State manager that owns all form state. Initialized via connectDeps() to guarantee
4044
+ * FORM_STATE_DEPS is populated before FormStateManager is injected. */
4045
+ private readonly stateManager;
4336
4046
  private componentId;
4337
4047
  /** The currently active config used for form rendering */
4338
4048
  activeConfig: Signal<FormConfig<TFields, InferFormValue$1<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]>, Record<string, unknown>, unknown> | undefined>;
@@ -4370,7 +4080,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4370
4080
  /** Whether any form field has been touched (blurred) */
4371
4081
  touched: Signal<boolean>;
4372
4082
  /** Current validation errors from all fields */
4373
- errors: Signal<_angular_forms_signals.ValidationError.WithField[]>;
4083
+ errors: Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
4374
4084
  /** Whether the form is disabled (from options or form state) */
4375
4085
  disabled: Signal<boolean>;
4376
4086
  /** Whether the form is currently submitting */
@@ -4381,6 +4091,13 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4381
4091
  shouldRender: Signal<boolean>;
4382
4092
  /** Resolved fields ready for rendering */
4383
4093
  protected resolvedFields: Signal<ResolvedField[]>;
4094
+ /**
4095
+ * Recursively counts container components that will emit ComponentInitializedEvent.
4096
+ * Includes the dynamic-form component itself (+1).
4097
+ *
4098
+ * Recurses into all container children, including those nested inside array
4099
+ * item templates, to avoid a premature (initialized) emission.
4100
+ */
4384
4101
  private totalComponentsCount;
4385
4102
  initialized$: rxjs.Observable<boolean>;
4386
4103
  /** Emits when form validity changes. */
@@ -4426,11 +4143,176 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
4426
4143
  */
4427
4144
  protected onNativeSubmit(event: Event): void;
4428
4145
  private setupEffects;
4146
+ /**
4147
+ * Populates FORM_STATE_DEPS with this component's input signals, then injects
4148
+ * FormStateManager. Must be called as a field initializer (after the input signals
4149
+ * are declared) so that FormStateManager reads populated deps when it is constructed.
4150
+ * inject() is valid here because field initializers run inside the injection context.
4151
+ */
4152
+ private connectDeps;
4429
4153
  private setupEventHandlers;
4430
4154
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicForm<any, any>, never>;
4431
4155
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicForm<any, any>, "form[dynamic-form]", never, { "config": { "alias": "dynamic-form"; "required": true; "isSignal": true; }; "formOptions": { "alias": "formOptions"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "validityChange": "validityChange"; "dirtyChange": "dirtyChange"; "submitted": "submitted"; "reset": "reset"; "cleared": "cleared"; "events": "events"; "initialized": "initialized"; "onPageChange": "onPageChange"; "onPageNavigationStateChange": "onPageNavigationStateChange"; }, never, never, true, never>;
4432
4156
  }
4433
4157
 
4158
+ declare class EventBus {
4159
+ private readonly pipeline$;
4160
+ private readonly globalEmitFormValue;
4161
+ private readonly rootFormRegistry;
4162
+ private readonly formOptions;
4163
+ private readonly logger;
4164
+ events$: Observable<FormEvent>;
4165
+ /**
4166
+ * Dispatches a pre-created event instance directly.
4167
+ *
4168
+ * Use this overload with the `arrayEvent()` factory or any other code that
4169
+ * produces a `FormEvent` instance rather than a constructor:
4170
+ *
4171
+ * ```typescript
4172
+ * eventBus.dispatch(arrayEvent('contacts').append(template));
4173
+ * eventBus.dispatch(arrayEvent('contacts').pop());
4174
+ * ```
4175
+ *
4176
+ * @param event - A FormEvent instance to dispatch
4177
+ */
4178
+ dispatch(event: FormEvent): void;
4179
+ /**
4180
+ * Dispatches an event to all subscribers by instantiating the provided constructor.
4181
+ *
4182
+ * Creates an instance of the provided event constructor and broadcasts it
4183
+ * through the event pipeline to all active subscribers.
4184
+ *
4185
+ * If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
4186
+ * is set to `true` in the form config, the current form value will be attached
4187
+ * to the event's `formValue` property.
4188
+ *
4189
+ * @param eventConstructor - Constructor function for the event to dispatch
4190
+ * @param args - Arguments to pass to the event constructor
4191
+ *
4192
+ * @example
4193
+ * ```typescript
4194
+ * // Dispatch a submit event
4195
+ * eventBus.dispatch(SubmitEvent);
4196
+ *
4197
+ * // Dispatch a custom event with args
4198
+ * eventBus.dispatch(CustomFormEvent, 'arg1', 42);
4199
+ * ```
4200
+ */
4201
+ dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
4202
+ /**
4203
+ * Dispatches a pre-created event instance directly.
4204
+ * Used internally by EventDispatcher to forward events into the bus.
4205
+ * @internal
4206
+ */
4207
+ emitInstance(event: FormEvent): void;
4208
+ /**
4209
+ * Shared emit path for both dispatch() and emitInstance().
4210
+ * Attaches form value if configured, then pushes to the pipeline.
4211
+ */
4212
+ private emit;
4213
+ /**
4214
+ * Emits an event through the pipeline. Catches any synchronous exception that escapes
4215
+ * RxJS's own error handling so dispatch() callers are never disrupted by a failing subscriber.
4216
+ */
4217
+ private safeEmit;
4218
+ /**
4219
+ * Determines whether form value should be attached to events.
4220
+ *
4221
+ * Precedence rules:
4222
+ * 1. Per-form setting (if defined) takes precedence
4223
+ * 2. Falls back to global setting
4224
+ */
4225
+ private shouldEmitFormValue;
4226
+ /**
4227
+ * Subscribes to events of a specific type.
4228
+ *
4229
+ * @param eventType - The type of event to subscribe to
4230
+ * @returns Observable that emits events of the specified type
4231
+ */
4232
+ on<T extends FormEvent>(eventType: T['type']): Observable<T>;
4233
+ /**
4234
+ * Subscribes to events of multiple types.
4235
+ *
4236
+ * @param eventType - Array of event types to subscribe to
4237
+ * @returns Observable that emits events matching any of the specified types
4238
+ */
4239
+ on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
4240
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
4241
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
4242
+ }
4243
+
4244
+ /**
4245
+ * Injectable service for dispatching events into a DynamicForm from outside the form.
4246
+ *
4247
+ * ## When to use
4248
+ *
4249
+ * Use `EventDispatcher` when you need to drive form behaviour **from the host component** —
4250
+ * for example, appending array items in response to a field value change, triggering a form
4251
+ * reset from a toolbar button, or reacting to external application state.
4252
+ *
4253
+ * This is the recommended alternative to accessing the form's internals via `viewChild`.
4254
+ *
4255
+ * ## Setup
4256
+ *
4257
+ * Provide `EventDispatcher` at the **host component** level (not root). DynamicForm
4258
+ * automatically detects it and connects its internal event bus to the dispatcher.
4259
+ *
4260
+ * ```typescript
4261
+ * @Component({
4262
+ * providers: [EventDispatcher],
4263
+ * template: `<form [dynamic-form]="config" [(value)]="formValue"></form>`
4264
+ * })
4265
+ * export class MyComponent {
4266
+ * readonly dispatcher = inject(EventDispatcher);
4267
+ * readonly formValue = signal<Record<string, unknown>>({});
4268
+ *
4269
+ * constructor() {
4270
+ * effect(() => {
4271
+ * const category = this.formValue()?.['category'] as string | undefined;
4272
+ * if (category) {
4273
+ * this.dispatcher.dispatch(
4274
+ * arrayEvent('tasks').append([{ key: 'name', type: 'input', label: 'Task', value: category }])
4275
+ * );
4276
+ * }
4277
+ * });
4278
+ * }
4279
+ * }
4280
+ * ```
4281
+ *
4282
+ * ## Multi-form note
4283
+ *
4284
+ * If multiple `DynamicForm` instances exist under the same provider scope, **all forms**
4285
+ * will receive dispatched events. To target a specific form, scope the provider to a
4286
+ * wrapper component that contains only that form.
4287
+ *
4288
+ * ## What events can be dispatched
4289
+ *
4290
+ * Any `FormEvent` instance is accepted — array events, reset/clear events, custom events, etc.
4291
+ * The `arrayEvent()` builder is the recommended way to construct array manipulation events:
4292
+ *
4293
+ * ```typescript
4294
+ * dispatcher.dispatch(arrayEvent('tasks').append(template));
4295
+ * dispatcher.dispatch(arrayEvent('tasks').removeAt(0));
4296
+ * dispatcher.dispatch(new FormResetEvent());
4297
+ * ```
4298
+ */
4299
+ declare class EventDispatcher {
4300
+ private bus;
4301
+ /**
4302
+ * Dispatches a form event into the connected DynamicForm's event bus.
4303
+ * No-op if no form is currently connected.
4304
+ *
4305
+ * @param event - A FormEvent instance. Use the `arrayEvent()` builder for array operations.
4306
+ */
4307
+ dispatch(event: FormEvent): void;
4308
+ /** @internal - Called by DynamicForm on init */
4309
+ connect(bus: EventBus): void;
4310
+ /** @internal - Called by DynamicForm on destroy */
4311
+ disconnect(): void;
4312
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventDispatcher, never>;
4313
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventDispatcher>;
4314
+ }
4315
+
4434
4316
  /**
4435
4317
  * Base interface for dynamic form features.
4436
4318
  * Features are configuration options that can be passed to provideDynamicForm
@@ -5444,92 +5326,6 @@ declare function arrayEvent(arrayKey: string): {
5444
5326
  removeAt: (index: number) => RemoveAtIndexEvent;
5445
5327
  };
5446
5328
 
5447
- /**
5448
- * Event bus service for form-wide event communication.
5449
- *
5450
- * Provides type-safe event dispatching and subscription for form components
5451
- * to communicate without direct coupling. Uses RxJS observables for reactive
5452
- * event handling and supports both single event type and multiple event type subscriptions.
5453
- *
5454
- * @example
5455
- * ```typescript
5456
- * @Component({
5457
- * providers: [EventBus]
5458
- * })
5459
- * export class MyFormComponent {
5460
- * constructor(private eventBus: EventBus) {
5461
- * // Subscribe to form submission events
5462
- * this.eventBus.on<SubmitEvent>('submit').subscribe(() => {
5463
- * console.log('Form was submitted');
5464
- * });
5465
- *
5466
- * // Subscribe to multiple event types
5467
- * this.eventBus.on<SubmitEvent | FormResetEvent>(['submit', 'form-reset']).subscribe(event => {
5468
- * console.log('Form event:', event.type);
5469
- * });
5470
- * }
5471
- *
5472
- * onSubmit() {
5473
- * // Dispatch a submit event
5474
- * this.eventBus.dispatch(SubmitEvent);
5475
- * }
5476
- * }
5477
- * ```
5478
- */
5479
- declare class EventBus {
5480
- private readonly pipeline$;
5481
- private readonly globalEmitFormValue;
5482
- private readonly rootFormRegistry;
5483
- private readonly formOptions;
5484
- events$: Observable<FormEvent>;
5485
- /**
5486
- * Dispatches an event to all subscribers.
5487
- *
5488
- * Creates an instance of the provided event constructor and broadcasts it
5489
- * through the event pipeline to all active subscribers.
5490
- *
5491
- * If `withEventFormValue()` is enabled globally or `options.emitFormValueOnEvents`
5492
- * is set to `true` in the form config, the current form value will be attached
5493
- * to the event's `formValue` property.
5494
- *
5495
- * @param eventConstructor - Constructor function for the event to dispatch
5496
- *
5497
- * @example
5498
- * ```typescript
5499
- * // Dispatch a submit event
5500
- * eventBus.dispatch(SubmitEvent);
5501
- *
5502
- * // Dispatch a custom event
5503
- * eventBus.dispatch(CustomFormEvent);
5504
- * ```
5505
- */
5506
- dispatch<T extends FormEventConstructor>(eventConstructor: T, ...args: ConstructorParameters<T>): void;
5507
- /**
5508
- * Determines whether form value should be attached to events.
5509
- *
5510
- * Precedence rules:
5511
- * 1. Per-form setting (if defined) takes precedence
5512
- * 2. Falls back to global setting
5513
- */
5514
- private shouldEmitFormValue;
5515
- /**
5516
- * Subscribes to events of a specific type.
5517
- *
5518
- * @param eventType - The type of event to subscribe to
5519
- * @returns Observable that emits events of the specified type
5520
- */
5521
- on<T extends FormEvent>(eventType: T['type']): Observable<T>;
5522
- /**
5523
- * Subscribes to events of multiple types.
5524
- *
5525
- * @param eventType - Array of event types to subscribe to
5526
- * @returns Observable that emits events matching any of the specified types
5527
- */
5528
- on<T extends FormEvent>(eventType: Array<T['type']>): Observable<T>;
5529
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<EventBus, never>;
5530
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<EventBus>;
5531
- }
5532
-
5533
5329
  /**
5534
5330
  * Context for token resolution in event args
5535
5331
  */
@@ -5847,6 +5643,26 @@ declare function dynamicTextToObservable(value: DynamicText | undefined, injecto
5847
5643
  */
5848
5644
  declare function applyMetaToElement(element: Element, meta: FieldMeta | undefined, previouslyApplied: Set<string>): Set<string>;
5849
5645
 
5646
+ /**
5647
+ * Wraps a `Resource` so that the previous resolved value is preserved while the resource
5648
+ * is loading or reloading. This prevents UI flicker when params change and a new request
5649
+ * is in-flight — the consumer sees the stale value with a `loading`/`reloading` status
5650
+ * instead of `undefined`.
5651
+ *
5652
+ * Uses Angular's `resource.snapshot` + `resourceFromSnapshots` composition pattern.
5653
+ *
5654
+ * @example
5655
+ * ```typescript
5656
+ * const user = withPreviousValue(
5657
+ * resource({ params: () => userId(), loader: ({ params }) => fetchUser(params) })
5658
+ * );
5659
+ * // user.value() keeps the old user data during loading transitions
5660
+ * ```
5661
+ *
5662
+ * @experimental Uses Angular's experimental resource composition APIs.
5663
+ */
5664
+ declare function withPreviousValue<T>(input: Resource<T>): Resource<T>;
5665
+
5850
5666
  /**
5851
5667
  * Pipe that handles dynamic text resolution with support for static strings,
5852
5668
  * Observables, and Signals.
@@ -5894,6 +5710,7 @@ declare class RowFieldComponent {
5894
5710
  private readonly destroyRef;
5895
5711
  private readonly fieldRegistry;
5896
5712
  private readonly injector;
5713
+ protected readonly environmentInjector: EnvironmentInjector;
5897
5714
  private readonly eventBus;
5898
5715
  private readonly logger;
5899
5716
  field: _angular_core.InputSignal<RowField<readonly _ng_forge_dynamic_forms.RowAllowedChildren[]>>;
@@ -5923,6 +5740,7 @@ declare class GroupFieldComponent<TModel extends Record<string, unknown> = Recor
5923
5740
  private readonly fieldRegistry;
5924
5741
  private readonly parentFieldSignalContext;
5925
5742
  private readonly injector;
5743
+ protected readonly environmentInjector: EnvironmentInjector;
5926
5744
  private readonly eventBus;
5927
5745
  private readonly logger;
5928
5746
  private readonly fieldProcessors;
@@ -5946,7 +5764,7 @@ declare class GroupFieldComponent<TModel extends Record<string, unknown> = Recor
5946
5764
  readonly invalid: _angular_core.Signal<boolean>;
5947
5765
  readonly dirty: _angular_core.Signal<boolean>;
5948
5766
  readonly touched: _angular_core.Signal<boolean>;
5949
- readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.WithField[]>;
5767
+ readonly errors: _angular_core.Signal<_angular_forms_signals.ValidationError.WithFieldTree[]>;
5950
5768
  readonly disabled: _angular_core.Signal<boolean>;
5951
5769
  private readonly nestedFieldTree;
5952
5770
  private readonly groupFieldSignalContext;
@@ -5999,6 +5817,7 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
5999
5817
  private readonly fieldRegistry;
6000
5818
  private readonly parentFieldSignalContext;
6001
5819
  private readonly parentInjector;
5820
+ protected readonly environmentInjector: EnvironmentInjector;
6002
5821
  private readonly eventBus;
6003
5822
  private readonly logger;
6004
5823
  private readonly templateRegistry;
@@ -6007,7 +5826,7 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
6007
5826
  key: _angular_core.InputSignal<string>;
6008
5827
  className: _angular_core.InputSignal<string | undefined>;
6009
5828
  hidden: _angular_core.InputSignal<boolean>;
6010
- readonly hostClasses: _angular_core.Signal<string>;
5829
+ readonly hostClasses: Signal<string>;
6011
5830
  private readonly rawFieldRegistry;
6012
5831
  /**
6013
5832
  * Gets the auto-remove button FieldDef from normalization metadata.
@@ -6052,7 +5871,12 @@ declare class ArrayFieldComponent<TModel extends Record<string, unknown> = Recor
6052
5871
  */
6053
5872
  private readonly itemPositionMap;
6054
5873
  /** Read-only view of resolved items for template consumption. */
6055
- readonly resolvedItems: _angular_core.Signal<ResolvedArrayItem[]>;
5874
+ readonly resolvedItems: Signal<ResolvedArrayItem[]>;
5875
+ /**
5876
+ * Whether the array has reached its configured maxLength.
5877
+ * Exposed as a public signal so add-button components can bind [disabled]="atMaxLength()".
5878
+ */
5879
+ readonly atMaxLength: Signal<boolean>;
6056
5880
  /**
6057
5881
  * Caches the result of appending the auto-remove button to template arrays.
6058
5882
  * Keyed by template array reference — cache hits occur during recreate/resolution
@@ -6191,5 +6015,12 @@ declare class RootFormRegistryService {
6191
6015
  constructor(formValue: Signal<Record<string, unknown>>, rootForm: Signal<FieldTree<Record<string, unknown>> | undefined>);
6192
6016
  }
6193
6017
 
6194
- export { ARRAY_CONTEXT, AppendArrayItemEvent, ArrayFieldComponent, BUILT_IN_FIELDS, ConsoleLogger, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DynamicForm, DynamicFormError, DynamicFormLogger, DynamicTextPipe, EventBus, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FormClearEvent, FormResetEvent, GroupFieldComponent, InsertArrayItemEvent, NextPageEvent, NoopLogger, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, RootFormRegistryService, RowFieldComponent, ShiftArrayItemEvent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayEvent, arrayFieldMapper, baseFieldMapper, buildBaseInputs, createField, dynamicTextToObservable, evaluateNonFieldDisabled, evaluateNonFieldHidden, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isPropertyDerivationLogicConfig, isRowField, isSimplifiedArrayField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig, withValueExclusionDefaults };
6195
- export type { ArrayAllowedChildren, ArrayButtonConfig, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemContext, ArrayItemDefinitionTemplate, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, ButtonLogicContext, CheckedFieldComponent, ConditionalExpression, ContainerFieldTypes, CustomFnConfig, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DynamicFormFieldRegistry, DynamicText, EvaluationContext, ExtractField, ExtractFieldDefs, ExtractFormValue, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTypeDefinition, FieldWithValidation, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, HttpValidatorConfig, InferFormValue$1 as InferFormValue, LeafFieldTypes, Logger, LogicConfig, MapperFn, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, PageAllowedChildren, PageField, Prettify, PropertyDerivationLogicConfig, RegisteredFieldTypes, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WithInputSignals };
6018
+ /**
6019
+ * Injection token for configuring the initialization timeout in milliseconds.
6020
+ * Defaults to 10 seconds. When the timeout is reached, a warning is logged
6021
+ * and (initialized) emits true as a best-effort fallback.
6022
+ */
6023
+ declare const INITIALIZATION_TIMEOUT_MS: InjectionToken<number>;
6024
+
6025
+ export { ARRAY_CONTEXT, AppendArrayItemEvent, ArrayFieldComponent, BUILT_IN_FIELDS, ConsoleLogger, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DynamicForm, DynamicFormError, DynamicFormLogger, DynamicTextPipe, EventBus, EventDispatcher, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_OPTIONS, FormClearEvent, FormResetEvent, GroupFieldComponent, INITIALIZATION_TIMEOUT_MS, InsertArrayItemEvent, NextPageEvent, NoopLogger, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, RootFormRegistryService, RowFieldComponent, ShiftArrayItemEvent, SubmitEvent, applyMetaToElement, applyValidator, applyValidators, arrayEvent, arrayFieldMapper, baseFieldMapper, buildBaseInputs, createField, dynamicTextToObservable, evaluateNonFieldDisabled, evaluateNonFieldHidden, field, formConfig, getArrayLength, groupFieldMapper, hasFormValue, interpolateParams, isArrayField, isCheckedField, isContainerField, isDisplayOnlyField, isEqual, isFormStateCondition, isGroupField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isValueField, omit, pageFieldMapper, provideDynamicForm, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, textFieldMapper, withEventFormValue, withLoggerConfig, withPreviousValue, withValueExclusionDefaults };
6026
+ export type { ArrayAllowedChildren, ArrayButtonConfig, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemContext, ArrayItemDefinitionTemplate, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, ButtonLogicContext, CheckedFieldComponent, ConditionalExpression, ContainerFieldTypes, CustomFnConfig, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DynamicFormFieldRegistry, DynamicText, EvaluationContext, ExtractField, ExtractFieldDefs, ExtractFormValue, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTypeDefinition, FieldWithValidation, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, InferFormValue$1 as InferFormValue, LeafFieldTypes, Logger, LogicConfig, MapperFn, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, PageAllowedChildren, PageField, Prettify, RegisteredFieldTypes, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WithInputSignals };