Consolidate MangaCircus app, scraper, and Compose baseline
This commit is contained in:
1 parent
cfb2d79103
commit
eef4ffa07c
103 files changed
+9316
-172
No files matched your search
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
|
||||
async function writeJsonAtomic(file, value, io = fs) {
|
||||
const folder = path.dirname(file), name = path.basename(file);
|
||||
const temp = path.join(folder, `.${name}.${crypto.randomUUID()}.tmp`);
|
||||
await io.writeFile(temp, JSON.stringify(value, null, 2) + '\n');
|
||||
try {
|
||||
try { await io.rename(temp, file); return; }
|
||||
catch (error) {
|
||||
if (!['EPERM', 'EACCES', 'EBUSY', 'EEXIST'].includes(error.code)) throw error;
|
||||
}
|
||||
// Windows may refuse rename-over-existing. Keep the old JSON recoverable
|
||||
// until the replacement is safely in place; never delete it first.
|
||||
const backup = path.join(folder, `.old-${name}-${crypto.randomUUID()}`);
|
||||
await io.rename(file, backup);
|
||||
try { await io.rename(temp, file); }
|
||||
catch (error) {
|
||||
try { await io.rename(backup, file); }
|
||||
catch (restoreError) { error.message += `; previous JSON remains at ${backup}: ${restoreError.message}`; }
|
||||
throw error;
|
||||
}
|
||||
await io.rm(backup, { force: true });
|
||||
} finally { await io.rm(temp, { force: true }); }
|
||||
}
|
||||
|
||||
module.exports = { writeJsonAtomic };
|
||||
Reference in new issue
Block a user