store() declares a store, from any file of src/, and the name of its export is the name of the store. It takes an object, StoreConfig, or nothing.
src/warnings.ts
How to use a store, where its data is and how expiration works is in the guide. This page lists what exists.
store()
src/: the name of the export is the name of the store, and its file in data/ (or its keys in Redis, with storage: 'redis'). Per server unless scope: 'global' is given, with an expiration if expires is.
StoreConfig
What a file gives tostore().
'guild' (the default): the data is kept per server, and a function that runs in a server reads and writes the data of that server, with nothing to say. 'global': one set of data for the whole bot.Where the data is kept:
'file' (the default), a file in the data/ folder of the project, or 'redis', the Redis of REDIS_URL in .env. Only stores that say 'redis' write anything there.How long a value is kept, unless
set() says otherwise: a number and a unit, s, m, h or d, like '10m', '1d' or '1h30m'. Kept forever by default.StoreScope
StoreStorage
storage of its config names.
Store
Whatstore() returns: a declaration the framework finds in the exports of a file. It is a ScopedStore for the server the code runs in, plus:
in()
ScopedStore
A store, read and written for one server or for the whole bot.get()
key, or undefined when there is none, or it expired.
set()
value at key. The value must be JSON: no Date, Map or class instance.
update()
key and keeps what change returns, in one go: nothing written meanwhile is lost, even by another process. change receives undefined when there is no value yet, and may run again when the value changed in between: keep it a plain computation. The expiration stays what it was, unless options say otherwise.
increment()
by (1 by default, negative to take away) to the number at key, starting from 0, in one go like update(), and resolves with the new number. Only for a store of numbers.
delete()
key. true when there was one.
getMany()
undefined for a key that has none.
setMany()
options. Every value is checked before anything is written.
deleteAll()
prefix, or every value of the store (of the server, for a store per server) without one. Resolves with how many there were.
entries()
prefix, in no particular order. Expired ones are left out.
ttl()
key is still kept, in milliseconds: null when it is kept forever, undefined when there is no value.
StoreKey
[channel.id, message.id]), which entries() can then list by prefix.
StoreSetOptions
Whatset() and update() take besides the value.
How long the value is kept: a duration like
'10m', a Date, or null to keep it forever. The expires of the store by default.StoreEntry
One entry of a store, asentries() lists them.
Where the data lives
One file per store,data/<name>.json at the root of the project: { "version": 1, "entries": [[key, value, expiresAt], ...] }, with expiresAt in milliseconds since the epoch or null. Written shortly after a change, in one piece (a temporary file, then a rename), and when the bot stops. Expired entries are dropped when the file is read, when they are asked for, and every minute.
In production on several processes, the process you started keeps the data and answers the others over IPC.
With storage: 'redis', one Redis key per value: <name>:<part>:<part> (the server id is the first part of a store per server; :, *, ?, [, ], \ and % inside a part are written %XX), its value the JSON of the value, its expiration set on the key (PX), so Redis forgets it alone. chapterjs dev puts dev: in front of every key. entries() is a SCAN on the prefix. Every process reaches Redis itself. update() and increment() are a transaction (WATCH, MULTI, EXEC), run again on the new value when another process wrote the key in between, on a connection of their own (at most 4 at once per process, besides the main one); the updates of one key in one process wait for each other. The address comes from REDIS_URL and REDIS_PASSWORD (see the CLI reference); a Redis that does not answer stops dev and start before Discord is reached, and the connection comes back by itself once it was made.