diff --git a/packages/loot-core/default-filesystem.mjs b/packages/loot-core/default-filesystem.mjs index 0690f25268..beea903f12 100644 --- a/packages/loot-core/default-filesystem.mjs +++ b/packages/loot-core/default-filesystem.mjs @@ -23,9 +23,12 @@ export const sqlWasmPath = require.resolve('@jlongster/sql.js/dist/sql-wasm.wasm'); function migrationFileNames() { + // Sort so the embedded `dataFiles` order (and thus the worker bundle hash) is + // stable regardless of the filesystem's `readdirSync` ordering. return fs .readdirSync(migrationsDir) - .filter(name => name.endsWith('.sql') || name.endsWith('.js')); + .filter(name => name.endsWith('.sql') || name.endsWith('.js')) + .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)); } /** diff --git a/packages/loot-core/src/server/migrate/embedded-assets.test.ts b/packages/loot-core/src/server/migrate/embedded-assets.test.ts index abef641b24..207c20b513 100644 --- a/packages/loot-core/src/server/migrate/embedded-assets.test.ts +++ b/packages/loot-core/src/server/migrate/embedded-assets.test.ts @@ -39,10 +39,11 @@ describe('embedded default filesystem', () => { }); it('embeds the default database and sql.js wasm byte-for-byte', () => { - const { dataFiles, wasmBase64 } = collectEmbeddedAssets(); + const { dataFiles, index, wasmBase64 } = collectEmbeddedAssets(); const embeddedDb = Buffer.from(dataFiles['default-db.sqlite'], 'base64'); expect(embeddedDb.equals(fs.readFileSync(defaultDbPath))).toBe(true); + expect(index.split('\n').filter(Boolean)).toContain('default-db.sqlite'); const embeddedWasm = Buffer.from(wasmBase64, 'base64'); expect(embeddedWasm.equals(fs.readFileSync(sqlWasmPath))).toBe(true);