@praxisui/dynamic-form 9.0.5-rc.2 → 9.0.5-rc.21

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-form",
3
- "version": "9.0.5-rc.2",
3
+ "version": "9.0.5-rc.21",
4
4
  "description": "Angular dynamic form engine for Praxis UI: metadata-driven forms, hooks, and services integrating @praxisui/* packages.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -9,13 +9,13 @@
9
9
  "@angular/forms": "^21.0.0",
10
10
  "@angular/material": "^21.0.0",
11
11
  "@angular/router": "^21.0.0",
12
- "@praxisui/ai": "^9.0.5-rc.2",
13
- "@praxisui/dynamic-fields": "^9.0.5-rc.2",
14
- "@praxisui/metadata-editor": "^9.0.5-rc.2",
15
- "@praxisui/rich-content": "^9.0.5-rc.2",
16
- "@praxisui/settings-panel": "^9.0.5-rc.2",
17
- "@praxisui/visual-builder": "^9.0.5-rc.2",
18
- "@praxisui/core": "^9.0.5-rc.2",
12
+ "@praxisui/ai": "^9.0.5-rc.21",
13
+ "@praxisui/dynamic-fields": "^9.0.5-rc.21",
14
+ "@praxisui/metadata-editor": "^9.0.5-rc.21",
15
+ "@praxisui/rich-content": "^9.0.5-rc.21",
16
+ "@praxisui/settings-panel": "^9.0.5-rc.21",
17
+ "@praxisui/visual-builder": "^9.0.5-rc.21",
18
+ "@praxisui/core": "^9.0.5-rc.21",
19
19
  "rxjs": "^7.8.0"
20
20
  },
21
21
  "dependencies": {
@@ -27,16 +27,18 @@ source_of_truth:
27
27
  - "projects/praxis-ai/src/lib/core/services/agentic-authoring-turn-client.service.ts"
28
28
  - "projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.ts"
29
29
  - "projects/praxis-dynamic-form/src/lib/utils/prepare-submit-payload.ts"
30
+ - "projects/praxis-dynamic-form/src/lib/services/reactive-determination-runtime.service.ts"
30
31
  - "projects/praxis-dynamic-fields/src/lib/directives/dynamic-field-loader.directive.ts"
31
32
  - "projects/praxis-dynamic-fields/src/lib/components/editable-collection/editable-collection.component.ts"
32
33
  - "projects/praxis-core/src/lib/models/form/form-config.model.ts"
34
+ - "projects/praxis-core/src/lib/models/form/reactive-determination.model.ts"
33
35
  - "projects/praxis-core/src/lib/models/form/form-layout.model.ts"
34
36
  - "projects/praxis-core/src/lib/services/schema-normalizer.service.ts"
35
37
  - "projects/praxis-core/src/lib/services/dynamic-form.service.ts"
36
38
  - "projects/praxis-core/src/lib/models/form/rule-property.schema.ts"
37
39
  - "projects/praxis-dynamic-form/docs/layout-items-visual-blocks.md"
38
- source_of_truth_last_verified: "2026-07-16"
39
- last_updated: "2026-07-16"
40
+ source_of_truth_last_verified: "2026-08-12"
41
+ last_updated: "2026-08-12"
40
42
  toc: true
41
43
  sidebar: true
42
44
  tags:
@@ -73,6 +75,21 @@ Este documento e a referencia canonica da API JSON de praxis-dynamic-form.
73
75
  - `backConfig`, `presentation` e `schemaPrefs` permanecem fora de `FormConfig`, mas fazem parte oficialmente do documento autoral persistivel em `contextSnapshot`.
74
76
  - APIs de compatibilidade como `applyConfigFromAdapter(...)` continuam aceitando payloads legados/parciais com semantica `merge-compat`, preservando campos nao informados.
75
77
 
78
+ ## Backend-owned reactive determinations
79
+
80
+ - `x-ui.reactiveDeterminations` e lido exclusivamente do request schema exato retornado por `/schemas/filtered`; nao integra nem e persistido em `FormConfig`.
81
+ - O runtime aceita somente o contrato fechado normalizado por `normalizeReactiveDeterminations`: trigger `on-change`, scope de create/edit, capability `POST`, no maximo 64 bindings totais, JSON Pointers sem duplicidade ou sobreposicao hierarquica e provenance estrutural.
82
+ - `href`, request/response schemas e bindings sao compilados pelo Praxis Metadata. O Angular nao aceita callback, headers, method, URL ou write policy autorados pelo host/editor/LLM.
83
+ - Cada valor ou status relevante invalida imediatamente a geracao anterior, antes do debounce da proxima chamada; somente a geracao ainda autoritativa pode aplicar a resposta.
84
+ - Hrefs protocol-relative, com separadores codificados ou resolvidos fora da origem configurada da API falham de forma fechada.
85
+ - A resposta so e aplicada quando todos os bindings existem. Os controles alvo aninhados sao preenchidos antes da notificacao dos observers; determinacoes encadeadas recebem um unico sinal logico depois do commit completo, nao um disparo por output. A ordem da cadeia e derivada dos bindings existentes: downstream aguarda a geracao upstream e so executa apos outputs autoritativos ou inputs confirmados como inalterados. Output upstream `null`/`undefined` e geracao upstream com erro, invalida ou cancelada encerram downstream como `skipped`, sem chamada com dado ausente ou obsoleto. Se um controle rejeitar a escrita, o runtime tenta restaurar os anteriores e emite falha terminal. O resultado tem semantica fechada server-derived e substitui o draft alvo; o commit e um batch coordenado no cliente, sem promessa de transacao ACID.
86
+ - O estado permanece pending durante debounce, validacao assincrona e execucao. Uma tentativa de submit aguarda estabilizacao com timeout e repete a espera depois de hooks que podem alterar controles.
87
+ - Controles de output sao desabilitados transitoriamente como valores server-derived, sem mutar/persistir `FormConfig`; seus valores continuam em `getRawValue()`, `valueChange` e no payload de submit.
88
+ - `reactiveDeterminationExecuted` publica apenas IDs, paths, provenance, estado (`pending`, `success`, `skipped` ou `error`), duracao, correlation ID e motivo. Valores do formulario e da resposta nao participam da evidencia.
89
+ - Hosts compostos recebem estado agregado por `reactiveDeterminationPendingChange`. Antes de navegar ou fechar, devem consultar `hasPendingReactiveDeterminations()` e `hasUnsatisfiedReactiveDeterminations()` e aguardar `waitForReactiveDeterminations(timeoutMs?)`; retorno `false` indica timeout ou geração mais recente sem draft autoritativo e bloqueia a transição. Correlações canceladas recebem terminal `skipped/superseded`.
90
+ - Cascatas de opcoes continuam em `optionSource.dependsOn`; recommendations, side-effect refresh, backend validation e workflow actions permanecem capacidades separadas.
91
+ - O comando backend final continua responsavel por autorizacao, recomputacao e validacao de qualquer decisao consequente.
92
+
76
93
  ## AI assistant and semantic authoring boundary
77
94
 
78
95
  `praxis-dynamic-form` usa o copiloto semantico Praxis como superficie assistiva contextual, nao como fonte primaria de regra de negocio. O componente pode abrir o assistente a partir de controles de configuracao, floating help ou selecao do canvas, mas a presenca global, minimizacao e retomada da sessao pertencem ao `PraxisAssistantSessionRegistryService`.
@@ -591,7 +608,7 @@ No ecossistema Praxis, ele funciona tanto como runtime final quanto como superfi
591
608
  | `configPersistenceStrategy` | `'local-first' \| 'input-first'` | `'local-first'` | Active | Em `input-first`, os inputs fornecidos pelo host, inclusive `mode`, permanecem autoritativos sobre preferencias persistidas da mesma instancia. Combine com `layoutPolicy.persistence='transient'` em commands efemeros para nao carregar nem gravar layout local. |
592
609
  | `layout` | `FormLayout \| undefined` | `undefined` | Partial | Funciona como override estrutural em parte dos fluxos de layout/editor. |
593
610
  | `generatedLayoutPreset` | `'default' \| 'compactPresentation'` | `'default'` | Active | Usado apenas ao criar a configuracao inicial a partir de schema/metadata; nao reprocessa layouts persistidos ou authorados. |
594
- | `layoutPolicy` | `DynamicFormLayoutPolicy \| null` | `null` | Active | Politica opt-in para materializar layout a partir do schema atual. Use `source: 'schema'` com `persistence: 'transient'` para detalhe/read-only e command forms schema-driven sem persistir `sections` geradas nem reabrir configuracao local salva; politicas de host em `config`, como `helpPresentation`, continuam sendo aplicadas ao layout materializado. Em `mode='view'`, `intent: 'detail'` ou `preset: 'compactPresentation'` ativa apresentacao quando `presentationModeGlobal` nao foi informado; use `[presentationModeGlobal]=false` para controles read-only tradicionais. No preset `compactPresentation`, `x-ui.width` explicito empacota campos em linhas de 12 colunas e tem precedencia sobre `detailSummary.columns` por default; campos sem width permanecem full-width, a menos que `detailSummary.columns`/`responsiveColumns` declare a densidade do resumo. Use `detailSummary.widthPrecedence='summary'` quando a densidade do resumo read-only deve sobrescrever `x-ui.width` apenas nessa surface compacta. No preset `groupedCommand`, `groupedCommand.orphanFieldExpansion` controla linhas com um unico campo: `medium-and-wide` (default) expande spans 6/8, `preserve` mantem o width publicado e `all` tambem expande campos compactos. `groupedCommand.partialRowStrategy` usa `preserve` por default; `fill-compatible` projeta linhas parciais elegiveis em spans canônicos que completam 12 colunas por breakpoint/container, sem alterar `x-ui.width`, `sections` ou o documento de authoring. Controles compactos, uploads e tipos desconhecidos preservam seus spans. `groupedCommand.contextFields` identifica campos schema-backed já hidratados pela surface: eles permanecem no `FormGroup` e no payload, mas não renderizam controles redundantes. Use `responsiveColumns`, por exemplo `{ lg: 3, md: 2, sm: 1 }`, para drawers, side sheets e painéis corporativos estreitos sem copiar `FormConfig.sections` locais. `schemaType` e `schemaOperation` sao validados contra `schemaUrl` quando a URL declara esses parametros. |
611
+ | `layoutPolicy` | `DynamicFormLayoutPolicy \| null` | `null` | Active | Politica opt-in para materializar layout a partir do schema atual. Use `source: 'schema'` com `persistence: 'transient'` para detalhe/read-only e command forms schema-driven sem persistir `sections` geradas nem reabrir configuracao local salva; politicas de host em `config`, como `helpPresentation`, continuam sendo aplicadas ao layout materializado. Em `mode='view'`, `intent: 'detail'` ou `preset: 'compactPresentation'` ativa apresentacao quando `presentationModeGlobal` nao foi informado; use `[presentationModeGlobal]=false` para controles read-only tradicionais. No preset `compactPresentation`, `x-ui.width` explicito empacota campos em linhas de 12 colunas e tem precedencia sobre `detailSummary.columns` por default; campos sem width permanecem full-width, a menos que `detailSummary.columns`/`responsiveColumns` declare a densidade do resumo. Use `detailSummary.widthPrecedence='summary'` quando a densidade do resumo read-only deve sobrescrever `x-ui.width` apenas nessa surface compacta. No preset `groupedCommand`, `groupedCommand.orphanFieldExpansion` controla linhas logicas com um unico campo: `medium-and-wide` (default) expande spans 6/8, `preserve` mantem o width publicado e `all` tambem expande campos compactos. `groupedCommand.partialRowStrategy` usa `preserve` por default; `fill-compatible` particiona o grupo nas linhas visuais depois de resolver visibilidade responsiva, CSS `order` e wrap em cada breakpoint/container, projeta cada linha parcial elegivel em spans canônicos que completam 12 colunas e mapeia o resultado de volta as colunas authoradas apenas para renderizacao, sem alterar `x-ui.width`, `sections` ou o documento de authoring. Um singleton elegivel criado por wrap pode preencher sua linha visual; controles compactos, uploads e tipos desconhecidos preservam seus spans. `groupedCommand.contextFields` identifica campos schema-backed já hidratados pela surface: eles permanecem no `FormGroup` e no payload, mas não renderizam controles redundantes. Use `responsiveColumns`, por exemplo `{ lg: 3, md: 2, sm: 1 }`, para drawers, side sheets e painéis corporativos estreitos sem copiar `FormConfig.sections` locais. `schemaType` e `schemaOperation` sao validados contra `schemaUrl` quando a URL declara esses parametros. |
595
612
 
596
613
  O authoring emite o warning `dynamicForm.config.layout.groupedCommand.row.incomplete` quando uma linha gerada com dois ou mais campos ocupa menos de 12 colunas. Com `partialRowStrategy='fill-compatible'`, o warning desaparece quando a projeção resolve a linha; ele permanece acionável para `preserve` ou quando controles compactos/fixos/desconhecidos não podem ser redistribuídos.
597
614
  | `backConfig` | `BackConfig \| undefined` | `undefined` | Active | Integra retorno/navegacao no painel de configuracao; `confirmOnDirty` tem precedencia sobre `behavior.confirmOnUnsavedChanges` no cancel. |
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { OnChanges, OnDestroy, EventEmitter, SimpleChanges, OnInit, ChangeDetectorRef, NgZone, Provider, AfterViewInit, ElementRef } from '@angular/core';
3
3
  import { HttpClient } from '@angular/common/http';
4
- import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
4
+ import { FormGroup, AbstractControl, FormBuilder, FormArray } from '@angular/forms';
5
5
  import { Router, ActivatedRoute } from '@angular/router';
6
6
  import { MatDialog } from '@angular/material/dialog';
7
7
  import { MatSnackBar } from '@angular/material/snack-bar';
8
8
  import { CdkDragStart, CdkDragMove, CdkDragEnd, CdkDragDrop } from '@angular/cdk/drag-drop';
9
9
  import * as _praxisui_core from '@praxisui/core';
10
- import { AsyncConfigStorage, FormLayout, FieldMetadata, FormLayoutRule, FormRuleTargetType as FormRuleTargetType$1, PraxisJsonLogicService, FormSection, FormRow, FormColumn, FormConfig, FormConfigWithSections, FormLayoutItem, FormActionButton, AiCapability, BackConfig, FormPresentationConfig, RichBlockHostCapabilities, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, FormHooksLayout, EndpointConfig, FormSubmitEvent, FormReadyEvent, FormValueChangeEvent, SyncResult, FormInitializationError, LoadingState, FormCustomActionEvent, FormActionConfirmationEvent, RichContentDocument, JsonLogicRecord, GenericCrudService, ConnectionStorage, DynamicFormService, ErrorMessageService, SchemaNormalizerService, ComponentMetadataRegistry, GlobalConfigService, ComponentKeyService, LoadingOrchestrator, ApiUrlConfig, PraxisLoadingRenderer, FormHooksRegistry, FormHookPreset, LoggerService, EnterpriseRuntimeContextService, FormSectionHeaderAction, FormSectionHeaderConfig, FormConfigState, JsonLogicExpression, FormHelpPresentationConfig, GlobalActionCatalogEntry, PraxisRuntimeConditionalEffectRule, PraxisRuntimeGlobalActionEffect, SurfaceOpenPayload, GlobalActionField, PraxisEffectPolicy, FieldDefinition, ComponentDocMeta, Breakpoint, DomainRuleRequestOptions, DomainRuleService, DomainRuleMaterialization, TableConfig, IconPickerService, GlobalActionRef, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
10
+ import { AsyncConfigStorage, FormLayout, FieldMetadata, FormLayoutRule, FormRuleTargetType as FormRuleTargetType$1, PraxisJsonLogicService, FormSection, FormRow, FormColumn, FormConfig, FormConfigWithSections, FormLayoutItem, ReactiveDeterminationDefinition, ReactiveDeterminationExecutionEvent, FormActionButton, AiCapability, BackConfig, FormPresentationConfig, RichBlockHostCapabilities, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, FormHooksLayout, EndpointConfig, FormSubmitEvent, FormReadyEvent, FormValueChangeEvent, SyncResult, FormInitializationError, LoadingState, FormCustomActionEvent, FormActionConfirmationEvent, RichContentDocument, JsonLogicRecord, GenericCrudService, ConnectionStorage, DynamicFormService, ErrorMessageService, SchemaNormalizerService, ComponentMetadataRegistry, GlobalConfigService, ComponentKeyService, LoadingOrchestrator, ApiUrlConfig, PraxisLoadingRenderer, FormHooksRegistry, FormHookPreset, LoggerService, EnterpriseRuntimeContextService, FormSectionHeaderAction, FormSectionHeaderConfig, FormConfigState, JsonLogicExpression, FormHelpPresentationConfig, GlobalActionCatalogEntry, PraxisRuntimeConditionalEffectRule, PraxisRuntimeGlobalActionEffect, SurfaceOpenPayload, GlobalActionField, PraxisEffectPolicy, FieldDefinition, ComponentDocMeta, Breakpoint, DomainRuleRequestOptions, DomainRuleService, DomainRuleMaterialization, TableConfig, IconPickerService, GlobalActionRef, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
11
11
  import * as rxjs from 'rxjs';
12
- import { Observable, BehaviorSubject } from 'rxjs';
12
+ import { Observable, Subscription, BehaviorSubject } from 'rxjs';
13
13
  import { SettingsPanelService, SettingsValueProvider } from '@praxisui/settings-panel';
14
14
  import { BaseAiAdapter, AiResponseCompileResult, PatchResult, PraxisAssistantShellLayout, PraxisAssistantTurnViewState, PraxisAssistantShellLabels, PraxisAssistantSessionSnapshot, PraxisAssistantShellQuickReply, PraxisAssistantShellMessage } from '@praxisui/ai';
15
15
  import { KeyboardShortcutService } from '@praxisui/dynamic-fields';
@@ -361,6 +361,42 @@ declare class DynamicFormLayoutService {
361
361
  static ɵprov: i0.ɵɵInjectableDeclaration<DynamicFormLayoutService>;
362
362
  }
363
363
 
364
+ type ReactiveDeterminationExecutor = (definition: ReactiveDeterminationDefinition, requestBody: Record<string, unknown>, correlationId: string) => Observable<Record<string, unknown>>;
365
+ /** Internal scheduler for Metadata-compiled, backend reactive determinations. */
366
+ declare class ReactiveDeterminationRuntimeService {
367
+ private readonly pendingStateByForm;
368
+ private readonly ownedTargetsByForm;
369
+ private readonly committedControlsByForm;
370
+ private readonly publishingCommitByForm;
371
+ private nextConnectionId;
372
+ hasPending(form: FormGroup): boolean;
373
+ hasUnsatisfied(form: FormGroup): boolean;
374
+ waitForStable(form: FormGroup, timeoutMs?: number): Promise<boolean>;
375
+ observePending(form: FormGroup, observer: (pending: boolean) => void): Subscription;
376
+ isOwnedTarget(form: FormGroup, control: AbstractControl): boolean;
377
+ connect(form: FormGroup, definitions: ReactiveDeterminationDefinition[], executor: ReactiveDeterminationExecutor, onEvent?: (event: ReactiveDeterminationExecutionEvent) => void, operationTimeoutMs?: number): Subscription;
378
+ private resolveControls;
379
+ private waitForUpstreamDeterminations;
380
+ private claimTargets;
381
+ private buildInvocation;
382
+ private buildCommit;
383
+ private commit;
384
+ private getOrCreateCommittedControls;
385
+ private event;
386
+ private getOrCreatePendingState;
387
+ private beginGeneration;
388
+ private satisfyGeneration;
389
+ private finishGeneration;
390
+ private clearDeterminationState;
391
+ private isCurrentGeneration;
392
+ private isPending;
393
+ private isSatisfied;
394
+ private notifyIfStable;
395
+ private notifyPendingChange;
396
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReactiveDeterminationRuntimeService, never>;
397
+ static ɵprov: i0.ɵɵInjectableDeclaration<ReactiveDeterminationRuntimeService>;
398
+ }
399
+
364
400
  declare class CanvasStateService {
365
401
  private readonly _hoveredElement$;
366
402
  readonly hoveredElement$: rxjs.Observable<CanvasElement | null>;
@@ -678,6 +714,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
678
714
  private snackBar;
679
715
  private canvasState;
680
716
  private dynamicLayout;
717
+ private reactiveDeterminationRuntime;
681
718
  private errorMessages;
682
719
  private schemaNormalizer;
683
720
  private componentMetaRegistry;
@@ -842,8 +879,14 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
842
879
  fieldRenderError: EventEmitter<DynamicFieldRenderErrorEvent>;
843
880
  /** Emits runtime rule diagnostics so hosts can surface or log invalid rules. */
844
881
  ruleDiagnosticsChange: EventEmitter<RuleApplicationDiagnostic[]>;
882
+ /** Emits metadata-only diagnostics for backend-owned form determinations. */
883
+ reactiveDeterminationExecuted: EventEmitter<ReactiveDeterminationExecutionEvent>;
884
+ /** Emits only aggregate runtime state; no request or response payload is exposed. */
885
+ reactiveDeterminationPendingChange: EventEmitter<boolean>;
886
+ private reactiveDeterminationPending;
845
887
  isLoading: boolean;
846
888
  submitting: boolean;
889
+ private submitPreparationInProgress;
847
890
  submitError: string | null;
848
891
  initializationStatus: 'idle' | 'loading' | 'success' | 'error';
849
892
  currentErrorMessage: string;
@@ -885,8 +928,13 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
885
928
  private readonly formConfigPersistenceGenerations;
886
929
  private readonly formConfigConflictBlockThrough;
887
930
  private schemaRootHooks?;
931
+ private schemaRootReactiveDeterminations;
932
+ private schemaRootOperationId;
888
933
  private destroy$;
934
+ private isDestroyed;
889
935
  private formValueChangesSubscription;
936
+ private reactiveDeterminationSubscription;
937
+ private reactiveDeterminationScheduledBuildId;
890
938
  private dependencyPolicySubscription;
891
939
  private formBuildCycleId;
892
940
  private suppressedValueChangeBuildId;
@@ -970,7 +1018,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
970
1018
  protected isMounting: boolean;
971
1019
  private hasBuiltFormFromConfig;
972
1020
  private runtimeFieldMetadata;
973
- constructor(crud: GenericCrudService<any>, http: HttpClient, fb: FormBuilder, cdr: ChangeDetectorRef, layoutService: FormLayoutService, contextService: FormContextService, rulesService: FormRulesService, settingsPanel: SettingsPanelService, dialog: MatDialog, asyncConfigStorage: AsyncConfigStorage, connectionStorage: ConnectionStorage, dynamicForm: DynamicFormService, snackBar: MatSnackBar, canvasState: CanvasStateService, dynamicLayout: DynamicFormLayoutService, errorMessages: ErrorMessageService, schemaNormalizer: SchemaNormalizerService, componentMetaRegistry: ComponentMetadataRegistry, global: GlobalConfigService, componentKeys: ComponentKeyService, loadingOrchestrator: LoadingOrchestrator, ngZone: NgZone, apiUrlConfig: ApiUrlConfig, loadingRenderer?: PraxisLoadingRenderer | undefined, router?: Router | undefined, route?: ActivatedRoute | undefined, hooksRegistry?: FormHooksRegistry | undefined, hookPresets?: FormHookPreset[] | null | undefined, logger?: LoggerService | undefined, enterpriseRuntimeContext?: EnterpriseRuntimeContextService | undefined);
1021
+ constructor(crud: GenericCrudService<any>, http: HttpClient, fb: FormBuilder, cdr: ChangeDetectorRef, layoutService: FormLayoutService, contextService: FormContextService, rulesService: FormRulesService, settingsPanel: SettingsPanelService, dialog: MatDialog, asyncConfigStorage: AsyncConfigStorage, connectionStorage: ConnectionStorage, dynamicForm: DynamicFormService, snackBar: MatSnackBar, canvasState: CanvasStateService, dynamicLayout: DynamicFormLayoutService, reactiveDeterminationRuntime: ReactiveDeterminationRuntimeService, errorMessages: ErrorMessageService, schemaNormalizer: SchemaNormalizerService, componentMetaRegistry: ComponentMetadataRegistry, global: GlobalConfigService, componentKeys: ComponentKeyService, loadingOrchestrator: LoadingOrchestrator, ngZone: NgZone, apiUrlConfig: ApiUrlConfig, loadingRenderer?: PraxisLoadingRenderer | undefined, router?: Router | undefined, route?: ActivatedRoute | undefined, hooksRegistry?: FormHooksRegistry | undefined, hookPresets?: FormHookPreset[] | null | undefined, logger?: LoggerService | undefined, enterpriseRuntimeContext?: EnterpriseRuntimeContextService | undefined);
974
1022
  private emitLoadingState;
975
1023
  private buildLoadingContext;
976
1024
  private beginLoading;
@@ -1027,6 +1075,16 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1027
1075
  private flushEntityHydrationState;
1028
1076
  private buildFormFromConfig;
1029
1077
  private resetFormValueChangesSubscription;
1078
+ private resetReactiveDeterminationSubscription;
1079
+ private scheduleReactiveDeterminationsActivation;
1080
+ /** True while at least one backend Reactive Determination is unsettled. */
1081
+ hasPendingReactiveDeterminations(): boolean;
1082
+ /** True when the latest settled generation failed or could not derive a current draft. */
1083
+ hasUnsatisfiedReactiveDeterminations(): boolean;
1084
+ /** Resolves true only when the latest generations settled successfully/current. */
1085
+ waitForReactiveDeterminations(timeoutMs?: number): Promise<boolean>;
1086
+ private setReactiveDeterminationPending;
1087
+ private handleReactiveDeterminationExecutionEvent;
1030
1088
  private resetDependencyPolicySubscription;
1031
1089
  private setupEntityLookupDependencyPolicies;
1032
1090
  private applyEntityLookupDependencyPolicy;
@@ -1193,6 +1251,8 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1193
1251
  private _executeAction;
1194
1252
  private getFormActionEventId;
1195
1253
  onSubmit(): Promise<void>;
1254
+ private prepareAndSubmit;
1255
+ private waitForReactiveDeterminationsBeforeSubmit;
1196
1256
  private applySubmitFieldErrors;
1197
1257
  private clearSubmitFieldErrors;
1198
1258
  private normalizeSubmitErrorTarget;
@@ -1394,8 +1454,8 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1394
1454
  private logRowGapsSnapshot;
1395
1455
  private applyPresentationVars;
1396
1456
  private applyPresentationConfig;
1397
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDynamicForm, [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
1398
- static ɵcmp: i0.ɵɵComponentDeclaration<PraxisDynamicForm, "praxis-dynamic-form", never, { "resourcePath": { "alias": "resourcePath"; "required": false; }; "resourceId": { "alias": "resourceId"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "editorialContext": { "alias": "editorialContext"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "config": { "alias": "config"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "schemaSource": { "alias": "schemaSource"; "required": false; }; "schemaUrl": { "alias": "schemaUrl"; "required": false; }; "readUrl": { "alias": "readUrl"; "required": false; }; "submitUrl": { "alias": "submitUrl"; "required": false; }; "submitMethod": { "alias": "submitMethod"; "required": false; }; "submitIdempotencyKey": { "alias": "submitIdempotencyKey"; "required": false; }; "submitCorrelationId": { "alias": "submitCorrelationId"; "required": false; }; "submitResourceVersion": { "alias": "submitResourceVersion"; "required": false; }; "responseSchemaUrl": { "alias": "responseSchemaUrl"; "required": false; }; "apiEndpointKey": { "alias": "apiEndpointKey"; "required": false; }; "apiUrlEntry": { "alias": "apiUrlEntry"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "showAiAssistant": { "alias": "showAiAssistant"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "configPersistenceStrategy": { "alias": "configPersistenceStrategy"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "generatedLayoutPreset": { "alias": "generatedLayoutPreset"; "required": false; }; "layoutPolicy": { "alias": "layoutPolicy"; "required": false; }; "backConfig": { "alias": "backConfig"; "required": false; }; "hooks": { "alias": "hooks"; "required": false; }; "removeEmptyContainersOnSave": { "alias": "removeEmptyContainersOnSave"; "required": false; }; "reactiveValidation": { "alias": "reactiveValidation"; "required": false; }; "reactiveValidationDebounceMs": { "alias": "reactiveValidationDebounceMs"; "required": false; }; "notifyIfOutdated": { "alias": "notifyIfOutdated"; "required": false; }; "snoozeMs": { "alias": "snoozeMs"; "required": false; }; "autoOpenSettingsOnOutdated": { "alias": "autoOpenSettingsOnOutdated"; "required": false; }; "readonlyModeGlobal": { "alias": "readonlyModeGlobal"; "required": false; }; "disabledModeGlobal": { "alias": "disabledModeGlobal"; "required": false; }; "presentationModeGlobal": { "alias": "presentationModeGlobal"; "required": false; }; "visibleGlobal": { "alias": "visibleGlobal"; "required": false; }; "fieldIconPolicy": { "alias": "fieldIconPolicy"; "required": false; }; "domainRules": { "alias": "domainRules"; "required": false; }; "customEndpoints": { "alias": "customEndpoints"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; "formReset": "formReset"; "configChange": "configChange"; "configPatchChange": "configPatchChange"; "formReady": "formReady"; "valueChange": "valueChange"; "syncCompleted": "syncCompleted"; "initializationError": "initializationError"; "loadingStateChange": "loadingStateChange"; "enableCustomizationChange": "enableCustomizationChange"; "customAction": "customAction"; "actionConfirmation": "actionConfirmation"; "schemaStatusChange": "schemaStatusChange"; "fieldRenderError": "fieldRenderError"; "ruleDiagnosticsChange": "ruleDiagnosticsChange"; }, never, never, true, never>;
1457
+ static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDynamicForm, [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
1458
+ static ɵcmp: i0.ɵɵComponentDeclaration<PraxisDynamicForm, "praxis-dynamic-form", never, { "resourcePath": { "alias": "resourcePath"; "required": false; }; "resourceId": { "alias": "resourceId"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "editorialContext": { "alias": "editorialContext"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "config": { "alias": "config"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "schemaSource": { "alias": "schemaSource"; "required": false; }; "schemaUrl": { "alias": "schemaUrl"; "required": false; }; "readUrl": { "alias": "readUrl"; "required": false; }; "submitUrl": { "alias": "submitUrl"; "required": false; }; "submitMethod": { "alias": "submitMethod"; "required": false; }; "submitIdempotencyKey": { "alias": "submitIdempotencyKey"; "required": false; }; "submitCorrelationId": { "alias": "submitCorrelationId"; "required": false; }; "submitResourceVersion": { "alias": "submitResourceVersion"; "required": false; }; "responseSchemaUrl": { "alias": "responseSchemaUrl"; "required": false; }; "apiEndpointKey": { "alias": "apiEndpointKey"; "required": false; }; "apiUrlEntry": { "alias": "apiUrlEntry"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "showAiAssistant": { "alias": "showAiAssistant"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "configPersistenceStrategy": { "alias": "configPersistenceStrategy"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "generatedLayoutPreset": { "alias": "generatedLayoutPreset"; "required": false; }; "layoutPolicy": { "alias": "layoutPolicy"; "required": false; }; "backConfig": { "alias": "backConfig"; "required": false; }; "hooks": { "alias": "hooks"; "required": false; }; "removeEmptyContainersOnSave": { "alias": "removeEmptyContainersOnSave"; "required": false; }; "reactiveValidation": { "alias": "reactiveValidation"; "required": false; }; "reactiveValidationDebounceMs": { "alias": "reactiveValidationDebounceMs"; "required": false; }; "notifyIfOutdated": { "alias": "notifyIfOutdated"; "required": false; }; "snoozeMs": { "alias": "snoozeMs"; "required": false; }; "autoOpenSettingsOnOutdated": { "alias": "autoOpenSettingsOnOutdated"; "required": false; }; "readonlyModeGlobal": { "alias": "readonlyModeGlobal"; "required": false; }; "disabledModeGlobal": { "alias": "disabledModeGlobal"; "required": false; }; "presentationModeGlobal": { "alias": "presentationModeGlobal"; "required": false; }; "visibleGlobal": { "alias": "visibleGlobal"; "required": false; }; "fieldIconPolicy": { "alias": "fieldIconPolicy"; "required": false; }; "domainRules": { "alias": "domainRules"; "required": false; }; "customEndpoints": { "alias": "customEndpoints"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; "formReset": "formReset"; "configChange": "configChange"; "configPatchChange": "configPatchChange"; "formReady": "formReady"; "valueChange": "valueChange"; "syncCompleted": "syncCompleted"; "initializationError": "initializationError"; "loadingStateChange": "loadingStateChange"; "enableCustomizationChange": "enableCustomizationChange"; "customAction": "customAction"; "actionConfirmation": "actionConfirmation"; "schemaStatusChange": "schemaStatusChange"; "fieldRenderError": "fieldRenderError"; "ruleDiagnosticsChange": "ruleDiagnosticsChange"; "reactiveDeterminationExecuted": "reactiveDeterminationExecuted"; "reactiveDeterminationPendingChange": "reactiveDeterminationPendingChange"; }, never, never, true, never>;
1399
1459
  }
1400
1460
 
1401
1461
  declare class FormConfigService {