diff --git a/packages/openontology/src/libsql.ts b/packages/openontology/src/libsql.ts index 0ef4dc1..a1eab05 100644 --- a/packages/openontology/src/libsql.ts +++ b/packages/openontology/src/libsql.ts @@ -225,13 +225,21 @@ export async function migrate(client: Client): Promise { let count = 0; for (const migration of MIGRATIONS) { if (have.has(migration.version)) continue; - for (const statement of migration.statements) { - await client.execute(statement); - } - await client.execute({ - sql: "INSERT INTO schema_migrations (version, name, applied_at) VALUES (?, ?, ?)", - args: [migration.version, migration.name, new Date().toISOString()] - }); + // One transaction per migration, rather than one implicit transaction per + // statement. Migration 1 alone is ~30 DDL statements, so opening a store + // used to cost ~30 durable commits; on a filesystem with slow fsync that + // dominated the open. It is also safer: a crash part-way can no longer + // leave the schema half-applied while schema_migrations claims it is done. + await client.batch( + [ + ...migration.statements, + { + sql: "INSERT INTO schema_migrations (version, name, applied_at) VALUES (?, ?, ?)", + args: [migration.version, migration.name, new Date().toISOString()] as InArgs + } + ], + "write" + ); count += 1; } return count; diff --git a/packages/openontology/vitest.config.ts b/packages/openontology/vitest.config.ts new file mode 100644 index 0000000..c366517 --- /dev/null +++ b/packages/openontology/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + // These suites drive a real file-backed SQLite database through + // @libsql/client, so their wall time is set by the host filesystem's + // durability cost, not by our code. Locally the whole libsql suite runs in + // ~250ms; on a contended CI runner a single seed-and-reopen case has been + // seen to pass 5s, which is vitest's default and is tuned for CPU-bound + // unit tests. Give the I/O-bound cases enough headroom that a slow disk + // reports as slow rather than as a spurious failure. + testTimeout: 30_000, + hookTimeout: 30_000 + } +});