fix: use pointer instead of payload in sessionStorage to prevent QuotaExceededError

Instead of storing full workflow JSON in sessionStorage (which can hit
quota on mobile), store only a small pointer to the draft path. The
actual workflow data lives in the draft store which has LRU eviction.

Loading priority:
1. SessionStorage pointer -> draft store
2. Preferred path -> draft store
3. Most recent draft (fallback)
4. Legacy sessionStorage payload (backward compat, remove after 2026-07-15)
5. Legacy localStorage payload (backward compat, remove after 2026-07-15)

This maintains duplicate-tab support while eliminating the quota issue.

Amp-Thread-ID: https://ampcode.com/threads/T-019bc597-fbea-778a-ae15-92061b3d0812
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
bymyself
2026-01-27 21:02:08 -08:00
parent 3d884976c4
commit aec1a55667
2 changed files with 16 additions and 21 deletions

View File

@@ -81,27 +81,12 @@ export function useWorkflowPersistence() {
return
}
// Store pointer in sessionStorage for duplicate-tab support (small, won't hit quota)
// The actual workflow data is stored in the draft store which has eviction
try {
localStorage.setItem('workflow', workflowJson)
if (api.clientId) {
sessionStorage.setItem(`workflow:${api.clientId}`, workflowJson)
}
} catch (error) {
// Only log our own keys and aggregate stats
const ourKeys = Object.keys(sessionStorage).filter(
(key) => key.startsWith('workflow:') || key === 'workflow'
)
console.error('QuotaExceededError details:', {
workflowSizeKB: Math.round(workflowJson.length / 1024),
totalStorageItems: Object.keys(sessionStorage).length,
ourWorkflowKeys: ourKeys.length,
ourWorkflowSizes: ourKeys.map((key) => ({
key,
sizeKB: Math.round(sessionStorage[key].length / 1024)
})),
error: error instanceof Error ? error.message : String(error)
})
throw error
sessionStorage.setItem('Comfy.Workflow.ActivePath', workflowPath)
} catch {
// Ignore - pointer is best-effort
}
lastSavedJsonByPath.value[workflowPath] = workflowJson

View File

@@ -124,17 +124,26 @@ export const useWorkflowDraftStore = defineStore('workflowDraft', () => {
fallbackToLatestDraft = false
} = options
// 1. Try sessionStorage pointer (for duplicate-tab support)
const sessionPath = sessionStorage.getItem('Comfy.Workflow.ActivePath')
if (sessionPath && (await loadDraft(sessionPath))) {
return true
}
// 2. Try preferred path from caller
if (preferredPath && (await loadDraft(preferredPath))) {
return true
}
if (!preferredPath && fallbackToLatestDraft) {
// 3. Fall back to most recent draft
if (fallbackToLatestDraft) {
const fallbackPath = mostRecentDraft.value
if (fallbackPath && (await loadDraft(fallbackPath))) {
return true
}
}
// 4. Legacy fallback: sessionStorage payload (remove after 2026-07-15)
const clientId = api.initialClientId ?? api.clientId
if (clientId) {
const sessionPayload = sessionStorage.getItem(`workflow:${clientId}`)
@@ -143,6 +152,7 @@ export const useWorkflowDraftStore = defineStore('workflowDraft', () => {
}
}
// 5. Legacy fallback: localStorage payload (remove after 2026-07-15)
const localPayload = localStorage.getItem('workflow')
return await tryLoadGraph(localPayload, workflowName)
}