Auto-Save Service
Relevant source files
The following files were used as context for generating this wiki page:
The Auto-Save Service is a singleton class responsible for preventing data loss by periodically saving versions of a user's design to local storage. It manages a version history for each design, allowing for restoration, deletion, and inspection of previous states. The service also provides a manual save mechanism, which was added to fix a critical bug where a direct save action was missing. The service's status is reflected in the UI, indicating to the user when a save is in progress or has completed.
The service leverages AsyncStorage for persistence and is configured through constants defined in the application's configuration files.
Sources: src/services/autoSaveService.js, CRITICAL_BUGS_FIXED.md, TASK_3_SUMMARY.md
Architecture
The AutoSaveService is implemented as a singleton class, meaning a single instance is created and shared throughout the application. It maintains an internal state including a timer for periodic saves, a flag for pending changes, and references to the current design being edited.
Sources: src/services/autoSaveService.js:345-348
Class Diagram
This diagram illustrates the key properties and methods of the AutoSaveService class.
Configuration
The service's behavior is controlled by the AUTO_SAVE object within src/config/constants.js.
| Key | Type | Default Value | Description |
|---|---|---|---|
ENABLED | Boolean | true | Globally enables or disables the auto-save feature. |
INTERVAL | Number | 30000 | The interval in milliseconds between save attempts (30 seconds). |
MAX_VERSIONS | Number | 10 | The maximum number of historical versions to keep per design. |
Sources: src/config/constants.js:332-336
Core Functionality
The service's primary functions revolve around a lifecycle of starting, tracking changes, and saving versions automatically or manually.
Lifecycle and Change Tracking
The auto-save process is initiated by calling start() and stopped with stop(). The markDirty() method is crucial for efficiency, as it flags that changes have occurred, making the design eligible for the next auto-save cycle.
Saving Versions
There are two ways to save a design: automatically via the timer or manually by invoking the save() method.
Manual Save (save)
A public save() method was added to address a critical bug where the "Save Design" button would crash the app because no such method existed. This method provides a way to force-save the current design, regardless of the pendingChanges state.
// src/services/autoSaveService.js:62-72
async save() {
if (!this.currentDesignId || !this.getCurrentDesign) {
console.warn('[AutoSave] Cannot save: no design ID or getter configured');
return null;
}
// Force save regardless of pendingChanges state
return await this.saveVersion(this.currentDesignId, this.getCurrentDesign());
}
Sources: src/services/autoSaveService.js:62-72, CRITICAL_BUGS_FIXED.md, AUDIT_FIXES_SUMMARY.md
saveVersion Process
This is the core internal method that handles the logic of creating and storing a new version.
This flowchart shows the steps taken within the saveVersion method.
Data and Storage
The service persists version data in AsyncStorage using a structured format.
Version Data Structure
Each saved version is an object containing metadata and the full design data.
| Field | Type | Description |
|---|---|---|
id | String | A unique identifier for the version, generated by generateId(). |
designId | String | The ID of the parent design. |
timestamp | String | An ISO 8601 timestamp of when the version was saved. |
data | Object | The complete design data object at the time of saving. |
size | Number | The size of the stringified design data in bytes. |
Sources: src/services/autoSaveService.js:80-86
Storage Schema
Versions for each design are stored under a unique key in AsyncStorage. The key is constructed using a prefix and the design ID.
${STORAGE_KEYS.DESIGNS}_versions_${designId}
STORAGE_KEYS.DESIGNS: The base key for designs, defined as'@designs'.designId: The unique identifier of the design being versioned.
The value stored is a JSON string representing an array of version objects.
Sources: src/services/autoSaveService.js:101-104, src/config/constants.js:132
Version Management API
The service exposes a rich API for managing the version history of a design.
| Method | Parameters | Returns | Description |
|---|---|---|---|
getVersions | designId | Promise<Array> | Retrieves all saved versions for a specific design. |
restoreVersion | designId, versionId | Promise<Object|null> | Finds a specific version by its ID and returns its data payload. |
deleteVersion | designId, versionId | Promise<boolean> | Removes a specific version from the history. |
clearVersions | designId | Promise<boolean> | Deletes all saved versions for a design. |
getVersionInfo | designId | Promise<Object|null> | Returns metadata about the version history (count, dates, total size). |
exportVersionHistory | designId | Promise<string|null> | Returns a JSON string of the version history (without full data). |
compareVersions | version1, version2 | Object | Compares two version data objects and returns added, removed, and modified elements. |