@bobfrankston/mailx-settings 0.1.91 → 0.1.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +15 -0
- package/index.d.ts.map +1 -1
- package/index.js +71 -14
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -235,6 +235,21 @@ export declare function loadAllowlistAsync(): Promise<typeof DEFAULT_ALLOWLIST>;
|
|
|
235
235
|
*/
|
|
236
236
|
export declare function mergeAllowlists(local: any, cloud: any, removals?: Record<string, string[]>): any;
|
|
237
237
|
export declare function saveAllowlist(list: typeof DEFAULT_ALLOWLIST, removals?: Record<string, string[]>): Promise<void>;
|
|
238
|
+
/** Crash-safe text write: tmp file → fsync → rename over the target.
|
|
239
|
+
*
|
|
240
|
+
* 2026-09-13 17:20 EDT — Claude Code (Fable 5.1), at Bob's direction.
|
|
241
|
+
* Added the fsync and exported this for every local-cache writer. Kernel-Power
|
|
242
|
+
* 41 crash at 16:36 today left `~/.rmfmail/accounts.jsonc` as 1932 NUL bytes:
|
|
243
|
+
* NTFS journals metadata (the new size) but not data, so a file rewritten
|
|
244
|
+
* moments before a hard crash comes back zero-filled. A rename alone does not
|
|
245
|
+
* close that window — the tmp file's data can be unflushed too — hence the
|
|
246
|
+
* fsync before the rename. The daemon then booted with 0 accounts. */
|
|
247
|
+
export declare function atomicWriteText(filePath: string, text: string): void;
|
|
248
|
+
/** Write `text` to `filePath` only when it differs from what is already there.
|
|
249
|
+
* Returns true when a write happened. Identical content is skipped so a
|
|
250
|
+
* periodic cloud poll doesn't keep the file in a perpetual just-written
|
|
251
|
+
* window (see atomicWriteText) and doesn't fire fs.watch for nothing. */
|
|
252
|
+
export declare function writeTextIfChanged(filePath: string, text: string): boolean;
|
|
238
253
|
/** Load user-added dictionary words. Mirrored to GDrive so "Add to dictionary"
|
|
239
254
|
* on one machine appears on every machine. Returns a deduped string array.
|
|
240
255
|
* Tries the cloud copy first (so a fresh machine sees prior words), then
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA0G3H,QAAA,MAAM,SAAS,QAA4E,CAAC;AA0E5F,qFAAqF;AACrF,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE;IAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAE/G,wBAAgB,YAAY,CAAC,EAAE,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAM/D;AAeD,iBAAS,YAAY,IAAI,MAAM,CAgB9B;AAsBD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import * as fs from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
-
import { parse as parseJsonc } from "jsonc-parser";
|
|
20
|
+
import { parse as parseJsonc, printParseErrorCode } from "jsonc-parser";
|
|
21
21
|
import { REMINDER_STATE_FILE, normalizeReminderState, mergeReminderStates, reminderStatesEqual } from "@bobfrankston/mailx-types";
|
|
22
22
|
import { getCloudProvider, gDriveFindOrCreateFolder, gDriveValidateCachedFolder } from "./cloud.js";
|
|
23
23
|
const __dirname = import.meta.dirname;
|
|
@@ -309,12 +309,23 @@ export async function cloudRead(filename) {
|
|
|
309
309
|
console.log(` [cloud] ${filename} changed locally during the read — keeping the local copy`);
|
|
310
310
|
}
|
|
311
311
|
else {
|
|
312
|
-
|
|
312
|
+
// 2026-09-13 17:20 EDT — Claude Code (Fable 5.1), at Bob's direction.
|
|
313
|
+
// Was an unconditional plain writeFileSync on EVERY cloud read —
|
|
314
|
+
// and pollCloud reads every 3 min — so accounts.jsonc was rewritten
|
|
315
|
+
// all day even when identical (the log showed "fs.watch fired but
|
|
316
|
+
// content unchanged" every 3 minutes). A kernel crash at 16:36
|
|
317
|
+
// today caught one of those rewrites and NTFS left the file
|
|
318
|
+
// zero-filled; the daemon then booted with 0 accounts. Now: skip
|
|
319
|
+
// when identical, and write crash-safe (tmp + fsync + rename).
|
|
313
320
|
stashPrev(filename, content);
|
|
314
|
-
|
|
321
|
+
writeTextIfChanged(path.join(LOCAL_DIR, filename), content);
|
|
315
322
|
}
|
|
316
323
|
}
|
|
317
|
-
catch {
|
|
324
|
+
catch (e) {
|
|
325
|
+
// The cloud content is still returned to the caller; only the local
|
|
326
|
+
// offline cache is stale, and the next read retries the write.
|
|
327
|
+
console.error(` [cloud] ${filename}: local cache write failed: ${e?.message || e}`);
|
|
328
|
+
}
|
|
318
329
|
}
|
|
319
330
|
// Don't set error for missing files — they may not exist yet (e.g., clients.jsonc on first run)
|
|
320
331
|
return content;
|
|
@@ -493,19 +504,31 @@ function readJsonc(filePath) {
|
|
|
493
504
|
return null;
|
|
494
505
|
}
|
|
495
506
|
try {
|
|
496
|
-
|
|
507
|
+
// 2026-09-13 17:20 EDT — Claude Code (Fable 5.1), at Bob's direction.
|
|
508
|
+
// jsonc-parser's parse() never throws: on garbage it returns undefined
|
|
509
|
+
// and only reports through the errors array. Without the array, the
|
|
510
|
+
// crash-zeroed accounts.jsonc (1932 NUL bytes) read as "no accounts"
|
|
511
|
+
// with not one log line — the daemon started with zero accounts and
|
|
512
|
+
// the only symptom was the "restart to apply" banner 14 s later.
|
|
513
|
+
const text = fs.readFileSync(actual, "utf-8").replace(/\r/g, "");
|
|
514
|
+
const errors = [];
|
|
515
|
+
const data = parseJsonc(text, errors);
|
|
516
|
+
if (errors.length > 0) {
|
|
517
|
+
const first = errors[0];
|
|
518
|
+
console.error(`Failed to parse ${actual}: ${printParseErrorCode(first.error)} at offset ${first.offset} (${errors.length} error(s), ${text.length} chars)`);
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
return data;
|
|
497
522
|
}
|
|
498
523
|
catch (e) {
|
|
499
524
|
console.error(`Failed to read ${actual}: ${e.message}`);
|
|
500
525
|
return null;
|
|
501
526
|
}
|
|
502
527
|
}
|
|
528
|
+
// 2026-09-13 17:20 EDT — Claude Code (Fable 5.1): one write mechanism; the
|
|
529
|
+
// fsync lives in atomicWriteText (see its note).
|
|
503
530
|
function atomicWrite(filePath, data) {
|
|
504
|
-
|
|
505
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
506
|
-
const tmp = filePath + ".tmp";
|
|
507
|
-
fs.writeFileSync(tmp, JSON.stringify(data, null, 2));
|
|
508
|
-
fs.renameSync(tmp, filePath);
|
|
531
|
+
atomicWriteText(filePath, JSON.stringify(data, null, 2));
|
|
509
532
|
}
|
|
510
533
|
/** Read a config file: shared first, local fallback, merge local overrides */
|
|
511
534
|
function loadFile(filename, defaults) {
|
|
@@ -827,8 +850,9 @@ export function loadAccounts() {
|
|
|
827
850
|
// semantic change, and that triggered the spurious banner.
|
|
828
851
|
const norm = (s) => s.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").replace(/[ \t\r\n]+$/, "");
|
|
829
852
|
if (norm(sharedContent) !== norm(localContent)) {
|
|
830
|
-
|
|
831
|
-
|
|
853
|
+
// 2026-09-13 17:20 EDT — Claude Code (Fable 5.1): crash-safe
|
|
854
|
+
// write (tmp + fsync + rename); see atomicWriteText.
|
|
855
|
+
atomicWriteText(localPath, sharedContent);
|
|
832
856
|
}
|
|
833
857
|
}
|
|
834
858
|
catch { /* ignore */ }
|
|
@@ -1318,13 +1342,46 @@ function buildDictCsv(words) {
|
|
|
1318
1342
|
const sorted = [...new Set(words)].filter(Boolean).sort((a, b) => a.localeCompare(b));
|
|
1319
1343
|
return "# rmfmail user dictionary — one word per line\n" + sorted.join("\n") + "\n";
|
|
1320
1344
|
}
|
|
1321
|
-
|
|
1345
|
+
/** Crash-safe text write: tmp file → fsync → rename over the target.
|
|
1346
|
+
*
|
|
1347
|
+
* 2026-09-13 17:20 EDT — Claude Code (Fable 5.1), at Bob's direction.
|
|
1348
|
+
* Added the fsync and exported this for every local-cache writer. Kernel-Power
|
|
1349
|
+
* 41 crash at 16:36 today left `~/.rmfmail/accounts.jsonc` as 1932 NUL bytes:
|
|
1350
|
+
* NTFS journals metadata (the new size) but not data, so a file rewritten
|
|
1351
|
+
* moments before a hard crash comes back zero-filled. A rename alone does not
|
|
1352
|
+
* close that window — the tmp file's data can be unflushed too — hence the
|
|
1353
|
+
* fsync before the rename. The daemon then booted with 0 accounts. */
|
|
1354
|
+
export function atomicWriteText(filePath, text) {
|
|
1322
1355
|
const dir = path.dirname(filePath);
|
|
1323
1356
|
fs.mkdirSync(dir, { recursive: true });
|
|
1324
1357
|
const tmp = filePath + ".tmp";
|
|
1325
|
-
fs.
|
|
1358
|
+
const fd = fs.openSync(tmp, "w");
|
|
1359
|
+
try {
|
|
1360
|
+
fs.writeSync(fd, text);
|
|
1361
|
+
fs.fsyncSync(fd);
|
|
1362
|
+
}
|
|
1363
|
+
finally {
|
|
1364
|
+
fs.closeSync(fd);
|
|
1365
|
+
}
|
|
1326
1366
|
fs.renameSync(tmp, filePath);
|
|
1327
1367
|
}
|
|
1368
|
+
/** Write `text` to `filePath` only when it differs from what is already there.
|
|
1369
|
+
* Returns true when a write happened. Identical content is skipped so a
|
|
1370
|
+
* periodic cloud poll doesn't keep the file in a perpetual just-written
|
|
1371
|
+
* window (see atomicWriteText) and doesn't fire fs.watch for nothing. */
|
|
1372
|
+
export function writeTextIfChanged(filePath, text) {
|
|
1373
|
+
let existing = null;
|
|
1374
|
+
try {
|
|
1375
|
+
existing = fs.readFileSync(filePath, "utf-8");
|
|
1376
|
+
}
|
|
1377
|
+
catch {
|
|
1378
|
+
existing = null; /* missing or unreadable → write it */
|
|
1379
|
+
}
|
|
1380
|
+
if (existing === text)
|
|
1381
|
+
return false;
|
|
1382
|
+
atomicWriteText(filePath, text);
|
|
1383
|
+
return true;
|
|
1384
|
+
}
|
|
1328
1385
|
/** Load user-added dictionary words. Mirrored to GDrive so "Add to dictionary"
|
|
1329
1386
|
* on one machine appears on every machine. Returns a deduped string array.
|
|
1330
1387
|
* Tries the cloud copy first (so a fresh machine sees prior words), then
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/mailx-settings",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.93",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
20
|
+
"@bobfrankston/mailx-types": "^0.1.100",
|
|
21
21
|
"jsonc-parser": "^3.3.1"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
".transformedSnapshot": {
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
36
|
+
"@bobfrankston/mailx-types": "^0.1.100",
|
|
37
37
|
"jsonc-parser": "^3.3.1"
|
|
38
38
|
}
|
|
39
39
|
}
|