Core Concepts
Understanding the moving pieces behind ng-form-cache makes it easier to reason about persistence, configure cleanup, and extend the system. This page explains the main concepts and how they interact during the draft lifecycle.
Drafts and metadata
Every autosaved form snapshot is stored as a StoredEntityData object. It bundles:
formData: the serializedFormGroupvalue.metadata: timestamps, version, the originating user, and the session id.entityType/entityId: logical identifiers you choose to scope drafts (for example"order"+"new").- Flags such as
isDirtyandautoSaveEnabledfor future UI scenarios.
The combination of entityType and entityId lets you manage multiple drafts per user.
User draft index
To keep track of all keys that belong to a user, ng-form-cache maintains a UserDraftIndex entry. It records the latest session id and every draft key associated with the user. The index enables fast cleanup without searching the entire storage namespace.
Session tracking
SessionManagerService assigns each browser tab (or application session) a generated id and stores it under the sessionIdKey (defaults to app_current_session_id). When a session starts or ends:
- The service writes the id into storage so other tabs stay in sync.
- The user draft index is updated with the new
sessionIdandlastActivitytimestamp. - When the tab closes or the session ends, the id is cleared to avoid resurrecting mixed drafts in the next login.
You can query sessionManagerService.isSessionValid(userId) to confirm that the stored drafts belong to the active session.
Autosave flow
- The
AutoSaveDirectivesubscribes toFormGroup.valueChangesand emits updates toFormPersistenceService.autoSave(...). FormPersistenceServicedebounces writes (autoSaveDebounceTime) and orchestrates serialization.- Drafts are persisted through the
FormCacheStorageadapter (localStorage by default). - The service also updates the user draft index so other features (cleanup, resume flows) can quickly list stored drafts.
When [fcAutoLoad]="true", the directive loads the newest draft as soon as the component mounts and optionally calls [fcNotifyFunc].
Cleanup strategy
CleanupService periodically executes three maintenance tasks:
- Expired drafts — removes entries whose
expiresAttimestamp is older thanDate.now(). - Stale sessions — deletes a user's drafts if
lastActivityexceeds the configuredstaleThreshold. - Quota management — when storage exceeds
storageQuota, the oldest 20% of drafts are pruned.
You can start or stop the scheduler manually (cleanupService.start() / cleanupService.stop()), but the default provider keeps it running in the background.
Configuration layers
Two configuration objects feed the system:
FormCacheConfig(FORM_CACHE_CONFIG): controls key prefixes, the session storage key, and debounce timings.PersistenceConfig(DRAFT_PERSISTENT_CONFIG): defines TTL, cleanup cadence, stale session threshold, and the approximate storage budget.
Use defaultConfig as a base and override pieces to align with your product constraints.
Storage abstraction
All persistence goes through the FormCacheStorage interface. The library ships with LocalStorageService, but you can bind a custom implementation. A storage adapter must:
- Read/write JSON objects by key (
getItem,setItem,removeItem,clear). - Generate normalized draft and index keys so cleanup can detect relevant entries.
- Fetch and store
StoredEntityDatainstances as well asUserDraftIndexrecords.
Because of this abstraction, you can synchronize drafts to remote APIs, use session storage, or encrypt data before writing to the browser.