Skip to content

Add IndexedDB schema migration framework and fix setInterval memory leak in UploadService#46

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/add-indexeddb-migration-strategy
Draft

Add IndexedDB schema migration framework and fix setInterval memory leak in UploadService#46
Copilot wants to merge 2 commits intomainfrom
copilot/add-indexeddb-migration-strategy

Conversation

Copy link

Copilot AI commented Mar 17, 2026

The database was hardcoded at v1 with no upgrade path, making future schema changes unsafe. Separately, clearInterval in uploadAsset was duplicated across try/catch, leaking the interval if anything threw unexpectedly.

IndexedDB migration framework (IndexedDBService.ts)

  • Bumped DB_VERSION 1 → 2
  • Introduced a migrations map keyed by version; onupgradeneeded now iterates oldVersion+1..newVersion and applies each migration in order
  • v1 migration preserves the original store/index creation; v2 adds the uploadAttempts index
const migrations: Record<number, (db: IDBDatabase, tx: IDBTransaction) => void> = {
  1: (db) => {
    const store = db.createObjectStore(STORE_NAME, { keyPath: 'id' });
    store.createIndex('status', 'status', { unique: false });
    // ...
  },
  2: (_db, tx) => {
    const store = tx.objectStore(STORE_NAME);
    if (!store.indexNames.contains('uploadAttempts')) {
      store.createIndex('uploadAttempts', 'uploadAttempts', { unique: false });
    }
  },
};

request.onupgradeneeded = (event) => {
  const db = request.result;
  const tx = request.transaction!;
  for (let v = event.oldVersion + 1; v <= (event.newVersion ?? DB_VERSION); v++) {
    migrations[v]?.(db, tx);
  }
};

Interval cleanup (UploadService.ts)

  • Replaced duplicate clearInterval in try + catch with a single call in finally, guaranteeing cleanup on all exit paths including re-thrown errors from handleUploadSuccess
Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature][Medium] Add IndexedDB schema migration strategy and fix memory leaks in upload progress simulation</issue_title>
<issue_description>## Summary

Two related reliability issues discovered during deep code review:

  1. IndexedDB has no schema migration capability — the database is locked at version 1 with no upgrade path, making it impossible to safely add new fields, indexes, or stores in future releases.
  2. setInterval memory leak in UploadService — progress simulation intervals can leak if the upload flow throws before the try block or if the error handler itself throws.

Finding 1: No IndexedDB Migration Strategy

Location

src/services/IndexedDBService.ts

Evidence

const DB_VERSION = 1;

request.onupgradeneeded = (event) => {
  const db = (event.target as IDBOpenDBRequest).result;
  if (!db.objectStoreNames.contains(STORE_NAME)) {
    const objectStore = db.createObjectStore(STORE_NAME, { keyPath: 'id' });
    objectStore.createIndex('status', 'status', { unique: false });
    objectStore.createIndex('createdAt', 'createdAt', { unique: false });
  }
};

Problem

  • Single version (v1) with no migration functions
  • onupgradeneeded only handles initial creation
  • Cannot add new required fields or indexes without breaking existing users
  • No data transformation on version bump
  • The Asset interface uses [key: string]: any as a workaround for extensibility, but this defeats TypeScript safety

Proposed Fix

const DB_VERSION = 2; // Increment when schema changes

const migrations: Record<number, (db: IDBDatabase, tx: IDBTransaction) => void> = {
  1: (db) => {
    const store = db.createObjectStore(STORE_NAME, { keyPath: 'id' });
    store.createIndex('status', 'status', { unique: false });
    store.createIndex('createdAt', 'createdAt', { unique: false });
  },
  2: (db, tx) => {
    const store = tx.objectStore(STORE_NAME);
    store.createIndex('uploadAttempts', 'uploadAttempts', { unique: false });
    // Transform existing records if needed
  },
};

request.onupgradeneeded = (event) => {
  const db = request.result;
  const tx = request.transaction!;
  for (let v = event.oldVersion + 1; v <= event.newVersion!; v++) {
    migrations[v]?.(db, tx);
  }
};

Finding 2: setInterval Memory Leak in Upload Progress

Location

src/services/UploadService.ts:239-296

Evidence

private startProgressSimulation(asset: Asset): ReturnType<typeof setInterval> {
  return setInterval(() => {
    // Updates progress every 500ms
  }, 500);
}

// In uploadAsset():
const progressInterval = this.startProgressSimulation(asset);
try {
  // Upload operations...
  clearInterval(progressInterval);  // Line 245
} catch (error) {
  clearInterval(progressInterval);  // Line 250
  throw error;
}

Problem

  • If code before the try block throws (after startProgressSimulation but before entering try), the interval leaks
  • If the catch handler itself throws during clearInterval, the interval leaks
  • Multiple failed uploads accumulate leaked intervals in the service worker

Proposed Fix

Use try/finally pattern:

const progressInterval = this.startProgressSimulation(asset);
try {
  // Upload operations...
} finally {
  clearInterval(progressInterval);  // Always cleaned up
}

Impact

  • Migration: Prevents data corruption when future versions need schema changes; unblocks safe feature development
  • Memory leak: Prevents background memory consumption from accumulated intervals in long-running service worker sessions

Files to modify

  • src/services/IndexedDBService.ts — add migration framework
  • src/services/UploadService.ts — fix interval cleanup pattern</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…mory leak

Co-authored-by: numbers-official <181934381+numbers-official@users.noreply.github.com>
Copilot AI changed the title [WIP] [Feature] Add IndexedDB schema migration strategy and fix memory leaks Add IndexedDB schema migration framework and fix setInterval memory leak in UploadService Mar 17, 2026
Copilot AI requested a review from numbers-official March 17, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature][Medium] Add IndexedDB schema migration strategy and fix memory leaks in upload progress simulation

2 participants