Skip to content

Commit 258d2b7

Browse files
authored
Fix initial start sample project load (#179)
* fix initialize db on first start issue * fix sample project loading
1 parent a2b42e8 commit 258d2b7

4 files changed

Lines changed: 501 additions & 462 deletions

File tree

cider-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"email": "contact@oatear.com",
77
"url": "https://oatear.com"
88
},
9-
"version": "0.6.13",
9+
"version": "0.6.14",
1010
"repository": "https://github.com/oatear/cider",
1111
"main": "electron-app/dist/main.js",
1212
"scripts": {

cider-app/src/app/data-services/indexed-db/db.ts

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Asset } from "../types/asset.type";
44
import { CardTemplate } from "../types/card-template.type";
55
import { FieldType } from "../types/field-type.type";
66
import { Deck } from "../types/deck.type";
7-
import { exportDB, importDB } from "dexie-export-import";
7+
import { exportDB, importDB, importInto } from "dexie-export-import";
88
import FileUtils from "src/app/shared/utils/file-utils";
99
import { ExportProgress } from "dexie-export-import/dist/export";
1010
import { ImportProgress } from "dexie-export-import/dist/import";
@@ -39,6 +39,7 @@ export class AppDB extends Dexie {
3939
private httpClient;
4040
private changeSubject: Subject<any>;
4141
private loadSubject: Subject<null>;
42+
private isPopulating: boolean = false;
4243

4344
constructor(httpClient: HttpClient,
4445
electronService: ElectronService,
@@ -151,9 +152,10 @@ export class AppDB extends Dexie {
151152
.then(count => {
152153
if (!electronService.isElectron() && count > 0) {
153154
console.log('db already populated');
155+
return Promise.resolve();
154156
} else {
155157
console.log('populate from file');
156-
this.populateFromFile().then(() => {
158+
return this.populateFromFile().then(() => {
157159
// cause asset urls to update
158160
this.loadSubject.next(null);
159161
});
@@ -176,7 +178,9 @@ export class AppDB extends Dexie {
176178

177179
// Add hooks for granular dirty tracking
178180
const trackChange = (tableName: string, type: string, key: any) => {
179-
this.changeSubject.next({ tableName, type, key });
181+
if (!this.isPopulating) {
182+
this.changeSubject.next({ tableName, type, key });
183+
}
180184
};
181185

182186
// We need to wait for tables to be initialized or just access them via this.table()
@@ -211,15 +215,39 @@ export class AppDB extends Dexie {
211215

212216
}
213217

214-
async populateFromFile() {
215-
const blob = await firstValueFrom(this.httpClient.get(AppDB.SAMPLE_DB_FILE, { responseType: 'blob' }));
216-
const file = new File([blob], 'database.json', { type: 'application/json', lastModified: Date.now() });
217-
return importDB(file, {
218-
//noTransaction: true
219-
}).then((db) => {
220-
this.initializeData();
221-
return db;
222-
});
218+
async populateFromFile(emitChange: boolean = true) {
219+
// This is a destructive operation, but it's only called when the DB is effectively empty
220+
// or we fully intend to reset to the sample state.
221+
this.isPopulating = true;
222+
223+
try {
224+
// 1. Fetch the sample file
225+
const blob = await firstValueFrom(this.httpClient.get(AppDB.SAMPLE_DB_FILE, { responseType: 'blob' }));
226+
const file = new File([blob], 'database.json', { type: 'application/json', lastModified: Date.now() });
227+
228+
// 2. Import into the CURRENT existing database logic
229+
// We do NOT close or delete the DB. We just clear existing tables and import data.
230+
// options:
231+
// - clearTablesBeforeImport: true -> effectively a reset
232+
// - acceptVersionDiff: true -> ignores that the file might be v2 and the DB is v10
233+
// - overwriteValues: true -> ensures import wins
234+
await importInto(this, file, {
235+
clearTablesBeforeImport: true,
236+
acceptVersionDiff: true,
237+
overwriteValues: true
238+
});
239+
240+
// 3. Notify that the database has been populated (refreshes UI/Sidebar)
241+
// We use a generic event so listeners know something changed.
242+
// We also wait a tick to ensure listeners are ready if this is part of initial load.
243+
if (emitChange) {
244+
this.changeSubject.next({ tableName: 'all', type: 'reset', key: null });
245+
}
246+
} finally {
247+
this.isPopulating = false;
248+
}
249+
250+
return this;
223251
}
224252

225253
/**
@@ -264,11 +292,13 @@ export class AppDB extends Dexie {
264292
public async resetDatabase(keepEmpty?: boolean) {
265293
this.close();
266294
await this.delete();
295+
await this.open();
267296
if (!keepEmpty) {
268-
const tempDb = await this.populateFromFile();
269-
tempDb.close();
297+
await this.populateFromFile(false);
298+
// Don't close here! populateFromFile leaves the DB open (via importInto),
299+
// and we want it to stay open for initializeData.
270300
}
271-
await this.open().then(() => this.initializeData());
301+
await this.initializeData();
272302
this.changeSubject.next(null);
273303
return true;
274304
}

0 commit comments

Comments
 (0)