chapterjs 0.3.0 → 0.4.0
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/README.md +2 -2
- package/dist/cli/build.js +14 -1
- package/dist/cli/dev.js +29 -1
- package/dist/cli/env.d.ts +5 -0
- package/dist/cli/env.js +39 -3
- package/dist/cli/project.d.ts +30 -7
- package/dist/cli/project.js +85 -11
- package/dist/cli/redis.d.ts +23 -0
- package/dist/cli/redis.js +57 -0
- package/dist/cli/start.js +43 -17
- package/dist/cli/test.js +4 -2
- package/dist/events/registry.d.ts +252 -239
- package/dist/events/registry.js +125 -100
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -0
- package/dist/ranking/declaration.d.ts +12 -0
- package/dist/ranking/declaration.js +48 -0
- package/dist/ranking/ranking.d.ts +102 -0
- package/dist/ranking/ranking.js +129 -0
- package/dist/redis/client.d.ts +36 -0
- package/dist/redis/client.js +252 -0
- package/dist/redis/protocol.d.ts +22 -0
- package/dist/redis/protocol.js +99 -0
- package/dist/redis/url.d.ts +24 -0
- package/dist/redis/url.js +50 -0
- package/dist/store/backend.d.ts +49 -4
- package/dist/store/backend.js +66 -11
- package/dist/store/declaration.d.ts +3 -0
- package/dist/store/declaration.js +8 -3
- package/dist/store/file-backend.d.ts +3 -1
- package/dist/store/file-backend.js +29 -0
- package/dist/store/ipc-backend.d.ts +24 -1
- package/dist/store/ipc-backend.js +49 -0
- package/dist/store/memory-backend.d.ts +4 -2
- package/dist/store/memory-backend.js +27 -1
- package/dist/store/ranking-backend.d.ts +45 -0
- package/dist/store/ranking-backend.js +82 -0
- package/dist/store/redis-backend.d.ts +38 -0
- package/dist/store/redis-backend.js +245 -0
- package/dist/store/redis-ranking.d.ts +15 -0
- package/dist/store/redis-ranking.js +69 -0
- package/dist/store/scope.d.ts +11 -0
- package/dist/store/scope.js +23 -0
- package/dist/store/store.d.ts +39 -5
- package/dist/store/store.js +79 -32
- package/dist/structures/invite.d.ts +6 -0
- package/dist/structures/invite.js +11 -0
- package/package.json +1 -1
package/dist/cli/start.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Nothing is reloaded, commands are registered for every server, and a
|
|
3
3
|
// large bot is spread over several processes by itself.
|
|
4
4
|
import { IpcStoreBackend } from '../store/ipc-backend.js';
|
|
5
|
+
import { NowhereToKeepError } from '../store/backend.js';
|
|
6
|
+
import { checkRedis, describeRedisStores, redisStores } from './redis.js';
|
|
5
7
|
import { registerCommands } from '../commands/register.js';
|
|
6
8
|
import { buildCommands } from '../commands/tree.js';
|
|
7
9
|
import { GLOBAL_REQUESTS_PER_SECOND } from '../discord/api.js';
|
|
@@ -13,7 +15,7 @@ import { connectToPrimary, planProcesses, REFUSED, runCluster, } from './cluster
|
|
|
13
15
|
import { loadBundle, readBuild } from './build.js';
|
|
14
16
|
import { readStartEnv } from './env.js';
|
|
15
17
|
import { describeIntents, ensurePrivilegedIntents, fetchApplication, } from './preflight.js';
|
|
16
|
-
import { createProject, explain } from './project.js';
|
|
18
|
+
import { createProject, explain, reportLooseRejections, } from './project.js';
|
|
17
19
|
/** Runs until stopped. Resolves with the exit code of the process. */
|
|
18
20
|
export async function start(options) {
|
|
19
21
|
const { cwd, log, signal } = options;
|
|
@@ -49,25 +51,30 @@ export async function start(options) {
|
|
|
49
51
|
}
|
|
50
52
|
return 1;
|
|
51
53
|
}
|
|
54
|
+
// Every process reaches Redis itself: it is made to be shared.
|
|
55
|
+
const redis = read.env.redis ? redisStores(read.env.redis, log) : null;
|
|
52
56
|
const project = createProject({
|
|
53
57
|
cwd,
|
|
54
58
|
version: options.version,
|
|
55
59
|
log,
|
|
56
60
|
built: files,
|
|
57
61
|
joinsVoice: built.info.voice === true,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
process.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
stores: {
|
|
63
|
+
// A process started by another keeps no file: the first one does,
|
|
64
|
+
// for all of them.
|
|
65
|
+
...(assignment
|
|
66
|
+
? {
|
|
67
|
+
file: new IpcStoreBackend({
|
|
68
|
+
send: message => {
|
|
69
|
+
if (process.connected)
|
|
70
|
+
process.send?.(message);
|
|
71
|
+
},
|
|
72
|
+
on: listener => process.on('message', listener),
|
|
73
|
+
}),
|
|
74
|
+
}
|
|
75
|
+
: {}),
|
|
76
|
+
...(redis ? { redis } : {}),
|
|
77
|
+
},
|
|
71
78
|
...(options.deferAfter === undefined
|
|
72
79
|
? {}
|
|
73
80
|
: { deferAfter: options.deferAfter }),
|
|
@@ -77,7 +84,12 @@ export async function start(options) {
|
|
|
77
84
|
for (const failure of failures)
|
|
78
85
|
project.report(failure);
|
|
79
86
|
if (!assignment) {
|
|
80
|
-
|
|
87
|
+
// A store kept in Redis without REDIS_URL is about the environment,
|
|
88
|
+
// not the build.
|
|
89
|
+
const unkept = failures.every(failure => failure.error instanceof NowhereToKeepError);
|
|
90
|
+
log.error(unkept
|
|
91
|
+
? 'The bot was not started. Give REDIS_URL to the bot the way your host does it (its "environment variables" or "secrets"), or in a .env file in this folder.'
|
|
92
|
+
: `${failures.length === 1 ? 'This file' : `These ${failures.length} files`} of the build can't run any more, so the bot was not started. Run "chapterjs build" again: it says what to fix.`);
|
|
81
93
|
}
|
|
82
94
|
return 1;
|
|
83
95
|
}
|
|
@@ -94,10 +106,18 @@ export async function start(options) {
|
|
|
94
106
|
? { guildFilter: (id) => id !== devGuildId }
|
|
95
107
|
: {}),
|
|
96
108
|
};
|
|
109
|
+
// A promise of the files left alone is an error of the file, not the end
|
|
110
|
+
// of the bot: in every process, since every one runs the files.
|
|
111
|
+
const loose = reportLooseRejections(cwd, log);
|
|
97
112
|
try {
|
|
98
113
|
if (assignment)
|
|
99
114
|
return await runShare(project, options, connection, assignment);
|
|
100
|
-
// 3. What Discord must agree with, checked once for every
|
|
115
|
+
// 3. What Redis, then Discord, must agree with, checked once for every
|
|
116
|
+
// process.
|
|
117
|
+
if (!(await checkRedis(project, redis, log))) {
|
|
118
|
+
await project.closeStores();
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
101
121
|
const rest = new RestClient({
|
|
102
122
|
token,
|
|
103
123
|
version: options.version,
|
|
@@ -132,6 +152,9 @@ export async function start(options) {
|
|
|
132
152
|
log.success(`Online as ${user} in ${guilds} ${guilds === 1 ? 'server' : 'servers'}${split ? ` (${split})` : ''}`);
|
|
133
153
|
log.info(`Intents computed from your files: ${describeIntents(intents)}`);
|
|
134
154
|
(project.isEmpty() ? log.info : log.success)(project.summary());
|
|
155
|
+
const kept = describeRedisStores(project, redis);
|
|
156
|
+
if (kept)
|
|
157
|
+
log.info(kept);
|
|
135
158
|
};
|
|
136
159
|
if (processes === 1) {
|
|
137
160
|
return await runAlone(project, options, connection, online);
|
|
@@ -146,7 +169,7 @@ export async function start(options) {
|
|
|
146
169
|
signal,
|
|
147
170
|
identifyInterval,
|
|
148
171
|
write: options.write,
|
|
149
|
-
stores: project.
|
|
172
|
+
stores: project.storeBackends.get('file'),
|
|
150
173
|
onReady: ({ user, guilds }) => online(user, guilds),
|
|
151
174
|
onRestart: (index, why) => log.warn(`Process ${index + 1} of ${processes} stopped by itself (${why}): starting it again. Its servers are back in a moment.`),
|
|
152
175
|
});
|
|
@@ -162,6 +185,9 @@ export async function start(options) {
|
|
|
162
185
|
explain(error, log);
|
|
163
186
|
return assignment ? REFUSED : 1;
|
|
164
187
|
}
|
|
188
|
+
finally {
|
|
189
|
+
loose();
|
|
190
|
+
}
|
|
165
191
|
}
|
|
166
192
|
/** Runs a bot until it is stopped or Discord refuses it. */
|
|
167
193
|
async function run(project, connection, stopped, connected, { tasks = true } = {}) {
|
package/dist/cli/test.js
CHANGED
|
@@ -67,7 +67,7 @@ function where(error, cwd) {
|
|
|
67
67
|
}
|
|
68
68
|
/** Runs the whole project in a fresh world; `close` ends it. */
|
|
69
69
|
async function startSession(project, observer, stores) {
|
|
70
|
-
stores.
|
|
70
|
+
stores.reset();
|
|
71
71
|
observer.reset();
|
|
72
72
|
const world = new World();
|
|
73
73
|
await world.start();
|
|
@@ -179,7 +179,9 @@ async function run(options, src, output) {
|
|
|
179
179
|
cwd,
|
|
180
180
|
version: options.version,
|
|
181
181
|
log: capture.log,
|
|
182
|
-
|
|
182
|
+
// Every store, wherever it says it keeps its data, is in memory here:
|
|
183
|
+
// a test never needs a Redis, and starts from nothing.
|
|
184
|
+
stores: { file: stores, redis: stores },
|
|
183
185
|
observe: observer.observe,
|
|
184
186
|
});
|
|
185
187
|
await writeTypes(cwd);
|