@p-sw/brainbox 0.1.2-alpha.6 → 0.1.2-alpha.8
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/dist/index.js +70 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { readFileSync as readFileSync2 } from "fs";
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7
|
-
import { dirname as dirname4, join as
|
|
7
|
+
import { dirname as dirname4, join as join5 } from "path";
|
|
8
8
|
|
|
9
9
|
// src/utils/logger.ts
|
|
10
10
|
import chalk from "chalk";
|
|
@@ -26,33 +26,52 @@ var ICONS = {
|
|
|
26
26
|
error: "✖",
|
|
27
27
|
fatal: "▲"
|
|
28
28
|
};
|
|
29
|
+
var shared = {
|
|
30
|
+
level: "info",
|
|
31
|
+
timestamps: true,
|
|
32
|
+
colors: chalk.level > 0,
|
|
33
|
+
file: undefined,
|
|
34
|
+
fileStream: undefined,
|
|
35
|
+
json: false,
|
|
36
|
+
silent: false
|
|
37
|
+
};
|
|
38
|
+
function openFile(path) {
|
|
39
|
+
if (path === shared.file)
|
|
40
|
+
return;
|
|
41
|
+
shared.fileStream?.end();
|
|
42
|
+
shared.file = path;
|
|
43
|
+
if (path) {
|
|
44
|
+
const dir = dirname(path);
|
|
45
|
+
if (!existsSync(dir))
|
|
46
|
+
mkdirSync(dir, { recursive: true });
|
|
47
|
+
shared.fileStream = createWriteStream(path, { flags: "a" });
|
|
48
|
+
} else {
|
|
49
|
+
shared.fileStream = undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function applyShared(options) {
|
|
53
|
+
if (options.level !== undefined)
|
|
54
|
+
shared.level = options.level;
|
|
55
|
+
if (options.timestamps !== undefined)
|
|
56
|
+
shared.timestamps = options.timestamps;
|
|
57
|
+
if (options.colors !== undefined)
|
|
58
|
+
shared.colors = options.colors;
|
|
59
|
+
if (options.silent !== undefined)
|
|
60
|
+
shared.silent = options.silent;
|
|
61
|
+
if (options.json !== undefined)
|
|
62
|
+
shared.json = options.json;
|
|
63
|
+
if ("file" in options)
|
|
64
|
+
openFile(options.file);
|
|
65
|
+
}
|
|
29
66
|
|
|
30
67
|
class Logger {
|
|
31
|
-
level;
|
|
32
|
-
timestamps;
|
|
33
|
-
colors;
|
|
34
68
|
tag;
|
|
35
|
-
file;
|
|
36
|
-
json;
|
|
37
|
-
silent;
|
|
38
|
-
fileStream;
|
|
39
69
|
constructor(options = {}) {
|
|
40
|
-
this.level = options.level ?? "info";
|
|
41
|
-
this.timestamps = options.timestamps ?? true;
|
|
42
|
-
this.colors = options.colors ?? chalk.level > 0;
|
|
43
70
|
this.tag = options.tag;
|
|
44
|
-
|
|
45
|
-
this.json = options.json ?? false;
|
|
46
|
-
this.silent = options.silent ?? false;
|
|
47
|
-
if (this.file) {
|
|
48
|
-
const dir = dirname(this.file);
|
|
49
|
-
if (!existsSync(dir))
|
|
50
|
-
mkdirSync(dir, { recursive: true });
|
|
51
|
-
this.fileStream = createWriteStream(this.file, { flags: "a" });
|
|
52
|
-
}
|
|
71
|
+
applyShared(options);
|
|
53
72
|
}
|
|
54
73
|
shouldLog(level) {
|
|
55
|
-
return LEVELS[level].rank >= LEVELS[
|
|
74
|
+
return LEVELS[level].rank >= LEVELS[shared.level].rank;
|
|
56
75
|
}
|
|
57
76
|
formatTimestamp() {
|
|
58
77
|
const now = new Date;
|
|
@@ -60,14 +79,14 @@ class Logger {
|
|
|
60
79
|
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
|
61
80
|
}
|
|
62
81
|
format(level, message) {
|
|
63
|
-
const ts =
|
|
82
|
+
const ts = shared.timestamps ? `[${this.formatTimestamp()}]` : "";
|
|
64
83
|
const tag = this.tag ? `[${this.tag}]` : "";
|
|
65
84
|
const icon = ICONS[level];
|
|
66
85
|
const levelStr = level.toUpperCase();
|
|
67
86
|
const consoleParts = [
|
|
68
87
|
ts,
|
|
69
88
|
tag,
|
|
70
|
-
|
|
89
|
+
shared.colors ? LEVELS[level].color(icon) : icon,
|
|
71
90
|
message
|
|
72
91
|
].filter(Boolean);
|
|
73
92
|
const consoleLine = consoleParts.join(" ");
|
|
@@ -90,13 +109,13 @@ class Logger {
|
|
|
90
109
|
return;
|
|
91
110
|
const { console: consoleLine, file: fileLine } = this.format(level, message);
|
|
92
111
|
const jsonLine = this.formatJson(level, message);
|
|
93
|
-
if (!
|
|
112
|
+
if (!shared.silent) {
|
|
94
113
|
const out = LEVELS[level].stderr ? process.stderr : process.stdout;
|
|
95
114
|
out.write(consoleLine + `
|
|
96
115
|
`);
|
|
97
116
|
}
|
|
98
|
-
if (
|
|
99
|
-
|
|
117
|
+
if (shared.fileStream) {
|
|
118
|
+
shared.fileStream.write(shared.json ? jsonLine : fileLine);
|
|
100
119
|
}
|
|
101
120
|
}
|
|
102
121
|
debug(message) {
|
|
@@ -119,44 +138,17 @@ class Logger {
|
|
|
119
138
|
}
|
|
120
139
|
child(tag) {
|
|
121
140
|
const combined = this.tag ? `${this.tag}:${tag}` : tag;
|
|
122
|
-
return new Logger({
|
|
123
|
-
level: this.level,
|
|
124
|
-
timestamps: this.timestamps,
|
|
125
|
-
colors: this.colors,
|
|
126
|
-
tag: combined,
|
|
127
|
-
file: this.file,
|
|
128
|
-
json: this.json,
|
|
129
|
-
silent: this.silent
|
|
130
|
-
});
|
|
141
|
+
return new Logger({ tag: combined });
|
|
131
142
|
}
|
|
132
143
|
configure(options) {
|
|
133
|
-
if (options.level !== undefined)
|
|
134
|
-
this.level = options.level;
|
|
135
|
-
if (options.timestamps !== undefined)
|
|
136
|
-
this.timestamps = options.timestamps;
|
|
137
|
-
if (options.colors !== undefined)
|
|
138
|
-
this.colors = options.colors;
|
|
139
144
|
if (options.tag !== undefined)
|
|
140
145
|
this.tag = options.tag;
|
|
141
|
-
|
|
142
|
-
this.silent = options.silent;
|
|
143
|
-
if (options.json !== undefined)
|
|
144
|
-
this.json = options.json;
|
|
145
|
-
if (options.file !== undefined && options.file !== this.file) {
|
|
146
|
-
this.fileStream?.end();
|
|
147
|
-
this.file = options.file;
|
|
148
|
-
if (this.file) {
|
|
149
|
-
const dir = dirname(this.file);
|
|
150
|
-
if (!existsSync(dir))
|
|
151
|
-
mkdirSync(dir, { recursive: true });
|
|
152
|
-
this.fileStream = createWriteStream(this.file, { flags: "a" });
|
|
153
|
-
} else {
|
|
154
|
-
this.fileStream = undefined;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
146
|
+
applyShared(options);
|
|
157
147
|
}
|
|
158
148
|
close() {
|
|
159
|
-
|
|
149
|
+
shared.fileStream?.end();
|
|
150
|
+
shared.fileStream = undefined;
|
|
151
|
+
shared.file = undefined;
|
|
160
152
|
}
|
|
161
153
|
}
|
|
162
154
|
var logger = new Logger;
|
|
@@ -3356,7 +3348,7 @@ class BaseChannel {
|
|
|
3356
3348
|
}, callback);
|
|
3357
3349
|
}
|
|
3358
3350
|
getRegisteredCrons() {
|
|
3359
|
-
return scheduledJobs.filter((c) => c.name && c.name.startsWith(this.resolveCronPrefix()))
|
|
3351
|
+
return scheduledJobs.filter((c) => c.name && c.name.startsWith(this.resolveCronPrefix()));
|
|
3360
3352
|
}
|
|
3361
3353
|
pauseCron(key) {
|
|
3362
3354
|
const job = scheduledJobs.find((c) => c.name === this.resolveCronName(key));
|
|
@@ -3447,6 +3439,13 @@ class BaseChannel {
|
|
|
3447
3439
|
this.isChattingDebounce = null;
|
|
3448
3440
|
}, IS_CHATTING_DEBOUNCE_MS);
|
|
3449
3441
|
}
|
|
3442
|
+
async initAvailability() {
|
|
3443
|
+
const current = await this.brain.getAvailability();
|
|
3444
|
+
this.previousAvailability = current.status;
|
|
3445
|
+
logger.debug(`initAvailability: ${current.status}`);
|
|
3446
|
+
await this.setAvailability(current.status);
|
|
3447
|
+
this.ensureAvailabilityWatcher();
|
|
3448
|
+
}
|
|
3450
3449
|
ensureAvailabilityWatcher() {
|
|
3451
3450
|
if (this.isCronStarted(AVAILABILITY_WATCHER_KEY))
|
|
3452
3451
|
return;
|
|
@@ -3456,6 +3455,9 @@ class BaseChannel {
|
|
|
3456
3455
|
const prev = this.previousAvailability;
|
|
3457
3456
|
this.previousAvailability = current.status;
|
|
3458
3457
|
logger.debug(`availabilityWatcher: ${prev ?? "(initial)"} → ${current.status}`);
|
|
3458
|
+
if (prev !== current.status) {
|
|
3459
|
+
await this.setAvailability(current.status);
|
|
3460
|
+
}
|
|
3459
3461
|
if (prev !== null && prev !== "online" && current.status === "online") {
|
|
3460
3462
|
await this.flushDeferred();
|
|
3461
3463
|
}
|
|
@@ -3516,8 +3518,8 @@ class BaseChannel {
|
|
|
3516
3518
|
logger.debug(`shutdown: done`);
|
|
3517
3519
|
}
|
|
3518
3520
|
stopOwnCrons() {
|
|
3519
|
-
for (const
|
|
3520
|
-
|
|
3521
|
+
for (const cron of this.getRegisteredCrons()) {
|
|
3522
|
+
cron.stop();
|
|
3521
3523
|
}
|
|
3522
3524
|
}
|
|
3523
3525
|
clearTimers() {
|
|
@@ -3627,6 +3629,7 @@ class DiscordChannel extends BaseChannel {
|
|
|
3627
3629
|
logger.debug(`DiscordClientReady: resolving configured channel ${channelId}`);
|
|
3628
3630
|
this.resolveConfiguredChannel(channelId);
|
|
3629
3631
|
}
|
|
3632
|
+
this.initAvailability();
|
|
3630
3633
|
});
|
|
3631
3634
|
this.client.on(Events.MessageCreate, (msg) => {
|
|
3632
3635
|
if (msg.author.bot)
|
|
@@ -3795,6 +3798,7 @@ class TelegramChannel extends BaseChannel {
|
|
|
3795
3798
|
this.registerActive();
|
|
3796
3799
|
this.bot.onStart(({ info }) => {
|
|
3797
3800
|
logger.success(`Telegram ready as @${info.username}`);
|
|
3801
|
+
this.initAvailability();
|
|
3798
3802
|
});
|
|
3799
3803
|
this.bot.on("message", (ctx) => {
|
|
3800
3804
|
if (ctx.from?.isBot())
|
|
@@ -3950,6 +3954,7 @@ function exchangeOnce(payload) {
|
|
|
3950
3954
|
// src/commands/daemon.ts
|
|
3951
3955
|
import { createServer } from "node:net";
|
|
3952
3956
|
import { chmodSync, unlinkSync } from "node:fs";
|
|
3957
|
+
import { join as join4 } from "node:path";
|
|
3953
3958
|
|
|
3954
3959
|
// src/commands/daemon/commands.ts
|
|
3955
3960
|
var log8 = logger.child("daemon-cmd");
|
|
@@ -4044,7 +4049,9 @@ async function startChannels() {
|
|
|
4044
4049
|
return started;
|
|
4045
4050
|
}
|
|
4046
4051
|
async function daemon() {
|
|
4047
|
-
|
|
4052
|
+
const logFile = join4(config.brainboxRoot, "brainbox.log");
|
|
4053
|
+
logger.configure({ file: logFile });
|
|
4054
|
+
logger.debug(`daemon: boot (log=${logFile})`);
|
|
4048
4055
|
const started = await startChannels();
|
|
4049
4056
|
if (started === 0) {
|
|
4050
4057
|
logger.info("No activated brains with channels. Daemon idling.");
|
|
@@ -5570,7 +5577,7 @@ logger.configure({ level: config.debug ? "debug" : "info" });
|
|
|
5570
5577
|
logger.debug(`brainbox starting (debug=${config.debug}, root=${config.brainboxRoot})`);
|
|
5571
5578
|
function getVersion() {
|
|
5572
5579
|
try {
|
|
5573
|
-
const pkgPath =
|
|
5580
|
+
const pkgPath = join5(__dirname3, "..", "package.json");
|
|
5574
5581
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
5575
5582
|
return pkg.version ?? "0.0.0";
|
|
5576
5583
|
} catch {
|