diff --git a/package-lock.json b/package-lock.json index e742181..d6d762c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.5.0", "license": "Apache-2.0", "dependencies": { - "@electric-sql/pglite": "^0.3.0", + "@electric-sql/pglite": "^0.5.4", "drizzle-orm": "^0.45.2", "exceljs": "^4.4.0", "next": "^15.5.4", @@ -28,9 +28,9 @@ } }, "node_modules/@electric-sql/pglite": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.3.16.tgz", - "integrity": "sha512-mZkZfOd9OqTMHsK+1cje8OSzfAQcpD7JmILXTl5ahdempjUDdmg4euf1biDex5/LfQIDJ3gvCu6qDgdnDxfJmA==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.5.4.tgz", + "integrity": "sha512-yYZUyyXrHU7tPlCjwZQJ6hIG9DscdCCn7Uk0mYKwC1FeHX286AbcmFveMiRBEak8e9iPupjsoVImN3yJZVed2g==", "license": "Apache-2.0" }, "node_modules/@emnapi/runtime": { diff --git a/package.json b/package.json index d5c3ef3..3ef4866 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.5.0", "private": true, "license": "Apache-2.0", - "description": "CAP Trellis \u2014 open-source client intake, eligibility, case & service management, and CSBG Annual Report 3.0 (OMB 0970-0492) reporting for Community Action Agencies", + "description": "CAP Trellis — open-source client intake, eligibility, case & service management, and CSBG Annual Report 3.0 (OMB 0970-0492) reporting for Community Action Agencies", "repository": { "type": "git", "url": "https://github.com/dchevalier18/csbg-intake.git" @@ -25,7 +25,7 @@ "uuid": "^11.1.1" }, "dependencies": { - "@electric-sql/pglite": "^0.3.0", + "@electric-sql/pglite": "^0.5.4", "drizzle-orm": "^0.45.2", "exceljs": "^4.4.0", "next": "^15.5.4", diff --git a/src/db/index.ts b/src/db/index.ts index cce2163..5efe96a 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -131,7 +131,20 @@ function createPgliteConn(): Conn { // PGlite's own mkdir is NOT recursive — a nested data dir (./data/pglite) // fails with ENOENT unless the parents exist. Create the full path first. if (dir && dir !== "memory") { - fs.mkdirSync(path.resolve(dir), { recursive: true }); + const abs = path.resolve(dir); + fs.mkdirSync(abs, { recursive: true }); + // A data dir a crashed instance left PARTIALLY initialized (e.g. killed + // mid-initdb) aborts every later open. A healthy PGlite dir always has a + // PG_VERSION file — quarantine anything non-empty without one (moved + // aside, never deleted) so the engine can initialize fresh. + const entries = fs.readdirSync(abs); + const healthy = entries.includes("PG_VERSION") && entries.includes("postgresql.conf"); + if (entries.length > 0 && !healthy) { + const quarantine = `${abs}.corrupt-${new Date().toISOString().replace(/[:.]/g, "-")}`; + fs.renameSync(abs, quarantine); + fs.mkdirSync(abs, { recursive: true }); + console.warn(`[db] embedded data dir was partially initialized — moved to ${quarantine} and starting fresh`); + } } // single in-process engine — no advisory lock needed (or available across processes); // embedded mode is for one local server, never for multi-process deployments