Member Junction
    Preparing search index...

    Save options used when saving an entity record. Provides fine-grained control over the save operation including validation, action execution, and conflict detection.

    Index

    Constructors

    Properties

    GraphVisited?: Set<string>

    Cycle guard: keys of the records already being persisted higher up in this unit of work.

    Set by the graph executor and threaded down through each child's Save() — that hop is why it lives on the options rather than staying inside the plan. A self-referential collection (SubAgents on MJ: AI Agents via ParentID, say) can otherwise recurse until the call stack dies, which surfaces as an unattributable crash instead of a fixable error.

    Not something callers set. Its lifetime is exactly one unit of work, which is deliberate — a process-global would be shared across concurrent requests and would report cycles that are really just two requests touching the same record at once.

    IgnoreDirtyState: boolean

    If set to true, the record will be saved to the database even if nothing is detected to be "dirty" or changed since the prior load.

    ISAActiveChildEntityName?: string

    The entity name of the child that initiated this parent save in an IS-A chain. Used by server-side providers to skip the active branch when propagating Record Change entries to sibling branches of overlapping parents. Only set when IsParentEntitySave is true.

    IsParentEntitySave?: boolean

    When true, this entity is being saved as part of an IS-A parent chain initiated by a child entity. Provider behavior:

    • GraphQLDataProvider: full ORM pipeline runs, skip network call
    • SQLServerDataProvider: real save using shared ProviderTransaction
    OnValidated?: (entity: BaseEntity) => void

    Optional callback invoked exactly once, after all pre-flight checks pass (synchronous Validate(), ValidateAsync(), and PreSave hooks) but before the record is persisted to the database. It receives the entity being saved.

    This is the framework hook for optimistic UI: a UI surface can render the user's change the moment it is known to be valid — without the "render then validation fails then roll back" flicker you get when you render before calling Save(). The await on Save() is still in place; only the visible render moves earlier.

    It does not fire when the save is skipped (not dirty / ReplayOnly) or when validation fails. Any error thrown by the callback is swallowed and logged so a UI bug can never abort the persistence it was meant to accompany. See guides/OPTIMISTIC_UI_SAVE_PATTERN.md.

    Receives the BaseEntity being saved (callers typically close over their own entity reference and ignore the parameter).

    OriginatingEntityActionIDs?: string[]

    IDs of the Entity Actions that caused this save — set by code writing back on behalf of one. Those actions will not be re-fired by this save's after-save hooks.

    This is the loop-breaker for enrich-and-write-back automations: an action running on AfterUpdate that stores its result on the same record would otherwise re-trigger itself forever. In-process that is detected automatically (the dispatch guard tracks origin through the async call tree), so this exists for work that has detached — a task graph executed later by the durable dispatcher, a queued job — where the ambient origin is long gone and the write-back is otherwise indistinguishable from a user's edit.

    Only after-save invocations are skipped. Validate and Before* still run: whether a record is legal does not depend on who is saving it.

    ReplayOnly?: boolean

    When set to true, the save operation will BYPASS Validate() and the actual process of saving changes to the database but WILL invoke any associated actions (AI Actions, Entity Actions, etc...) Subclasses can also override the Save() method to provide custom logic that will be invoked when ReplayOnly is set to true

    SkipAsyncValidation?: boolean

    When set to true, the entity will skip the asynchronous ValidateAsync() method during save. This is an advanced setting and should only be used when you are sure the async validation is not needed. The default behavior is to run the async validation and the default value is undefined. Also, you can set an Entity level default in a BaseEntity subclass by overriding the DefaultSkipAsyncValidation() getter property.

    BaseEntity.DefaultSkipAsyncValidation

    SkipEntityActions?: boolean

    If set to true, any Entity Actions associated with invocation types of Create or Update will be skipped during the save operation

    SkipEntityAIActions?: boolean

    If set to true, an AI actions associated with the entity will be skipped during the save operation

    SkipGeoCoding?: boolean

    When true, the save skips the geocoding side trip even when the entity has SupportsGeoCoding on. Same rationale and scoping as SkipRecordChanges: a synced record arrives pre-formed from the source system and does not need a per-write geocode lookup, while a human's edit to an address should still trigger one.

    SkipOldValuesCheck?: boolean

    Setting this to true means that the system will not look for inconsistency between the state of the record at the time it was loaded and the current database version of the record. This is normally on because it is a good way to prevent overwriting changes made by other users that happened after your version of the record was loaded. However, in some cases, you may want to skip this check, such as when you are updating a record that you know has not been changed by anyone else since you loaded it. In that case, you can set this property to true to skip the check which will be more efficient.

    • IMPORTANT: This is only used for client-side providers. On server-side providers, this check never occurs because server side operations are as up to date as this check would yield.
    SkipRecordChanges?: boolean

    When true, the save skips writing a Record Change (audit) row even when the entity has TrackRecordChanges on.

    This exists for high-volume MACHINE writes — an integration sync applying tens of thousands of records in minutes — where the audit row is a per-write cost with no value: the "who" is always the sync, and the real history lives in the source system. Scoping the suppression to the save (instead of turning the entity flag off) keeps the capability for every other writer: a human editing the same record through the UI is still audited, because their save never sets this option.

    SkipRelatedCollections?: boolean

    Persist owner-held embeds (and other non-collection companions) but skip RelatedRecordCollection nodes.

    Use this when the caller will write the collections itself after preparing them (pricing, expansion, sequence). The graph executor's recursion guard is private on BaseEntity — it is not a caller-facing "header-only" switch.