Problem Description
Clients are generating code that calls merge() without save(), expecting the changes to be automatically persisted to the database. However, merge() is designed as a setState replacement for local updates (e.g., every keystroke) and does not automatically save to the database.
Example Code
import React from "react"
import { useFireproof } from "use-fireproof"
export default function PageToggle() {
const { database, useDocument } = useFireproof("page-toggle-db")
const { doc, merge } = useDocument({ isWhite: false, type: "page-state" })
const togglePage = () => {
merge({ isWhite: !doc.isWhite }) // ❌ Changes local state but doesn't persist
}
return (
<div>
<button onClick={togglePage}>Toggle Page</button>
<div style={{ backgroundColor: doc.isWhite ? 'white' : 'black' }}>
Current state: {doc.isWhite ? 'White' : 'Black'}
</div>
</div>
)
}
Current Behavior vs Expected Behavior
Current Behavior:
merge() updates local component state only
- Changes are lost on page refresh/component unmount
- Requires explicit
save() call for persistence
Expected Behavior (by clients):
merge() changes should be automatically persisted
- State should survive page refreshes
- No manual
save() required for simple state updates
Impact
This creates a poor developer experience where:
- Clients write code that appears to work (UI updates)
- Data is lost unexpectedly on refresh
- Confusion about when persistence actually happens
- Need to remember to call
save() for every merge()
Potential Solutions
Option 1: Auto-save with Debouncing
Add automatic persistence to merge() with configurable debouncing:
const { doc, merge } = useDocument({
isWhite: false
}, {
autoSave: true, // Enable auto-save on merge
autoSaveDelay: 300 // Debounce delay in ms
});
Option 2: Auto-save on Unload
Automatically save pending changes when component unmounts or page unloads:
// Save any pending changes on cleanup
useEffect(() => {
return () => {
if (hasUnsavedChanges) {
save();
}
};
}, []);
Recommended Approach
Option 1 + 2 (Auto-save with Debouncing) seems most practical:
- Maintains backward compatibility
- Provides expected behavior for simple use cases
- Allows opt-out for performance-sensitive scenarios
- Handles both frequent updates and state changes appropriately
Implementation Considerations
- Performance: Auto-save should be debounced to avoid excessive database writes
- Error Handling: Failed auto-saves should not break the UI
- Opt-out: Developers should be able to disable auto-save for performance-critical components
- Migration: Existing code should continue to work unchanged
- Documentation: Clear guidance on when to use auto-save vs manual save
Related Files
use-fireproof/react/use-document.ts (line 65-68: merge implementation)
notes/use-document.md (documentation of current behavior)
This issue affects developer experience and could prevent adoption due to unexpected data loss.
Problem Description
Clients are generating code that calls
merge()withoutsave(), expecting the changes to be automatically persisted to the database. However,merge()is designed as asetStatereplacement for local updates (e.g., every keystroke) and does not automatically save to the database.Example Code
Current Behavior vs Expected Behavior
Current Behavior:
merge()updates local component state onlysave()call for persistenceExpected Behavior (by clients):
merge()changes should be automatically persistedsave()required for simple state updatesImpact
This creates a poor developer experience where:
save()for everymerge()Potential Solutions
Option 1: Auto-save with Debouncing
Add automatic persistence to
merge()with configurable debouncing:Option 2: Auto-save on Unload
Automatically save pending changes when component unmounts or page unloads:
Recommended Approach
Option 1 + 2 (Auto-save with Debouncing) seems most practical:
Implementation Considerations
Related Files
use-fireproof/react/use-document.ts(line 65-68: merge implementation)notes/use-document.md(documentation of current behavior)This issue affects developer experience and could prevent adoption due to unexpected data loss.