open source is social v-it.org
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2026 sol pbc
3
4import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from 'node:fs';
5import { join } from 'node:path';
6import { errorMessage } from './error-format.js';
7
8export function vitDir(dir) {
9 return join(dir || process.cwd(), '.vit');
10}
11
12export function readProjectConfig(dir) {
13 const p = join(vitDir(dir), 'config.json');
14 if (!existsSync(p)) return {};
15 try {
16 return JSON.parse(readFileSync(p, 'utf-8'));
17 } catch (err) {
18 console.warn(`warning: failed to read ${p}: ${errorMessage(err)}`);
19 return {};
20 }
21}
22
23export function readBeaconSet(dir) {
24 const config = readProjectConfig(dir);
25 const set = new Set();
26 if (config.beacon) set.add(config.beacon);
27 if (config.secondaryBeacon) set.add(config.secondaryBeacon);
28 return set;
29}
30
31export function writeProjectConfig(obj, baseDir) {
32 const dir = baseDir ? join(baseDir, '.vit') : vitDir();
33 mkdirSync(dir, { recursive: true });
34 writeFileSync(join(dir, 'config.json'), JSON.stringify(obj, null, 2) + '\n');
35}
36
37export function appendLog(filename, record, dir) {
38 const d = vitDir(dir);
39 mkdirSync(d, { recursive: true });
40 appendFileSync(join(d, filename), JSON.stringify(record) + '\n');
41}
42
43export function readLog(filename, dir) {
44 const p = join(vitDir(dir), filename);
45 if (!existsSync(p)) return [];
46 try {
47 return readFileSync(p, 'utf-8')
48 .split('\n')
49 .filter(line => line.trim())
50 .map((line, index) => {
51 try {
52 return JSON.parse(line);
53 } catch (err) {
54 console.warn(`warning: skipping malformed line ${index + 1} in ${p}: ${errorMessage(err)}`);
55 return null;
56 }
57 })
58 .filter(Boolean);
59 } catch (err) {
60 console.warn(`warning: failed to read ${p}: ${errorMessage(err)}`);
61 return [];
62 }
63}
64
65export function readFollowing(dir) {
66 const p = join(vitDir(dir), 'following.json');
67 if (!existsSync(p)) return [];
68 try {
69 return JSON.parse(readFileSync(p, 'utf-8'));
70 } catch (err) {
71 console.warn(`warning: failed to read ${p}: ${errorMessage(err)}`);
72 return [];
73 }
74}
75
76export function writeFollowing(list, dir) {
77 const d = vitDir(dir);
78 mkdirSync(d, { recursive: true });
79 writeFileSync(join(d, 'following.json'), JSON.stringify(list, null, 2) + '\n');
80}