#archive-library-discussion
25217 messages · Page 25 of 26
Hmm. That ones tough
can't we just
make proxy always return 429s
and let the client using the proxy handle the parsing/error throwing?
well, the library itself exposes a middleware function that takes in a REST instance that is already instantiated
so by all means, users are welcome to do that and it's easy to accomplish
if we end up exporting a binary/docker image that just starts up a v simple proxy to fulfil most people's needs
we could default to that, yes
this is more a crawl question but from my pov
my worker rest instance that connects to the proxy has its own rejectOnRatelimit
Proxy always tells me a 429 happened.
My worker instance decides to throw it or not
yea that makes sense
you might want to retry on the worker side
we can figure out such default behavior later when we actually make those binaries, but for now
back to the original topic
could REST support per-request rejectOnRatelimit?
i actually feel like this has more diverse usecase
better question is should it support that
well i can think of why it'd be good
the age old problem
discord bumps a ratelimit to hell and we don't know, our bot starts leaking memory because the poor sequential bucket handler gets queued requests faster than it handles them because of the ratelimits
we had this happen with channel names (no, not an obnoxious clock feature)
and we had no clue what was going on
we were queueing, say 3-4 reqs per 10 minutes and the limit is 2/10min
so I could it see it being beneficial to pass in the option for long limits that you know you don't want to wait for
@solemn oyster did you mean to do this in your last commit to #7934 https://sucks-to-b.eu/HjQrc3.png
Yes, check the reviews
I bumped those a bit too high, they should be using the same version as 13.7.0 does, which is 0.30.0
hi so
is there any reason declaration source maps are not enabled?
it would make working with the monorepo a shit load easier since VSCode "Go To Symbol" would actually take me to the definitions
hmm, the only thing proxy can't forward rn is headers for non-2xx status codes - DiscordAPIError has most of the relevant info (status text, status message, body etc) but not headers
I was thinking of how this could be accomplished and the only way would be to have REST#raw not throw - but rather return responses even when they're not 2xx. I think this would actually be desirable behavior
? cc @wild flax @tacit crypt
all though that becomes.. stupidly complicated to accomplish 
Iirc it would still jump to the .d.ts file with that enabled. I know the TS team is working on something to go directly to the source https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-rc/#go-to-source-definition
it works for me in my monorepo 👀
lemme test real quick to see if it works with djs (all though I don't see why it wouldn't), and if so I might PR
while I was working on that
why was this added in the undici PR lol https://sucks-to-b.eu/CJerc2.png
actually confused why that's in the repo - esp. given VSCode gives no easy option to bypass that once it's a workspace setting
well, after some research seems tsup doesn't support declaration source maps properly, so there goes that dream
I added that with the intent to remove it once the pr was ready but then crawl was fine with it staying in
Is there anything stopping #7929 (REST#raw) from being merged? just needs space to approve, right?
thanks for the merge. #7925 is now ready for review 
I've also added a section for current minor caveats that don't seem easily fixable but that we may or may not want to address
I'm also gonna be running some proper tests on it today to make sure it all works
I only skimmed the code
Is this like a full binary solution
Or is this just a middleware type of thing
middleware with some helpers to build ur own middleware
unsure how we wanna deal with binaries since djs has no precedent doing that afaik
would it even be in the package folder but ignored from npm publish
If it’s a library yeah like a middleware
oh hey im green now
But idk maybe we should make a separate repo
Where we make it a binary and docker image or smth
Because if it was a ready to deploy solution too, it’d be kinda nice
yea that's what I'm thinking too
so there's like
2 exported functions that help you populate a ServerResponse from either an error or a 200 response from discord so you can make your own stuff
and then there's a proxyRequests middleware
that just calls REST#raw in a try..catch
and calls the appropriate method
and ends the response
Yeah idk if you want to wrap this around a node http server
Lmk
I can make a repo for this
that's probs how the default binary would work no?
express etc seems like too much just for this
Yeah
yea ok
yea im setting up a little test project locally rn to see if it all works
and once we merge we can get a repo going for common usecases
There is something else but idk if it’s in node already
They did rewrite the http with some new thing
Kinda like undici
personally what i'll be using for my bot is something that a) logs & collects analytics and b) caches since I like dealing with cache at the proxy level much to your distaste :^)
yea def not the default one 
that's mostly a me thing
I guess the first one will just proxy and nothing else on top
and then people can like
"hey I have my own custom one that does X"
and if X is popular we can
add more, boom
sure
@wild flax 👀
// proxy.js - this will be our binary minus the worker stuff
import { createServer } from 'node:http';
import { proxyRequests } from '@discordjs/proxy';
import { REST } from '@discordjs/rest';
import { parentPort } from 'node:worker_threads';
const api = new REST({ version: '10', rejectOnRateLimit: () => true }).setToken(process.env.DISCORD_TOKEN);
const server = createServer(proxyRequests(api));
server.listen(parseInt(process.env.PORT, 10), () => {
parentPort.postMessage('ready');
});
// index.js
import { Worker, SHARE_ENV } from 'node:worker_threads';
import { Client, IntentsBitField } from 'discord.js';
import { ProxyAgent } from 'undici';
const client = new Client({
intents: [IntentsBitField.Flags.Guilds],
});
client.on('ready', () => {
console.log('ready');
process.exit(0);
});
client.rest.setAgent(new ProxyAgent(`http://localhost:${process.env.PORT}`));
const restWorker = new Worker('./proxy.js', { env: SHARE_ENV });
restWorker.once('message', () => {
console.log('rest worker ready');
client.login(process.env.DISCORD_TOKEN);
});
➜ node index.js
rest worker ready
ready```
works now
I'll probs test some other stuff here and there but generally speaking at least the gateway connects 
idk that was just for my test
I could've just booted it as its own process lol
but I think some people might be inclined to boot it in a worker if they're just using proxy to work around the /gateway/bot ratelimit we were talking about
if their bot is a monolith where they only start one process anyway it's probs easier for them to throw rest into a worker
alright, I'm actually done with my PR now unless changes are requested
Shouldn’t the threadCreate, threadDelete and threadUpdate events be integrated into channel<events>. Then the user can check if the channel is thread and do whatever
I’m not sure if this is already implemented since I don’t follow the GitHub updates that often
We don't change or manipulate events, we follow the Discord API which has them separate
Does not account for emojiCreate and emojiDelete...
Huh, good point, no idea why we do that, though its kinda the opposite example
Thats one event being split out rather than multiple events being merged together
I have nothing to say about it, just look at the pictures.
confused
maybe because... that isn't an accepted format? #fff is parsed as 0x000fff
although yeah that should throw an error instead of accepting it
pretty sure you are supposed to parse #fff as #ffffff
but that's not exactly a hex string, that's a shorthand hex string. tons of things don't support it.
Yeah, not standard
hmm can't we just validate with /^#?[\da-f]{6}$/i
and if that doesn't match then throw an error
cant install stuff into main branch. Need to push commits on the pr
[versions]
yarn -> 3.2.0
node -> 16.15.0
!node_modules 🫂
userUpdate was heavily changed and manipulated in djs iirc
Mon's message was a general statement
i agree, let's stop doing that 
fwiw I hate that, but the pushback for removing it is quite strong
Still voting for we should leave it as it comes from the API
anyone?
This isn't a support channel
Delete node_modules and start again
Yes but I have to commit to my pr and I cannot resolve this issue and it clearly seemed djs issue by reading the errors. This happens only on main branch.
Also there is no node_modules if you see the ss and trying to install node_modules using yarn or yarn install throws the errors from the above ss.
Idk how this aint library related.
in the slash command option classes, you all really need to adjust the names of the addChoice and addChoices methods. They're super easy to mistake particularly if your editor has autocomplete, and the error message you get from the validation is incredibly vague - makes debugging it a nightmare
i think that'll be resolved along with the addField/addFields thing for embeds
I'm happy to hear that 🙂
there's been a lot of discussion around their signatures and inclusion
addChoice has already been removed in the main version of the builders. I believe addField will follow suit
so in the future you'll have to add all choices as an array of string pairs, right?
They take a rest param so not an array, but yes it will take APIApplicationCommandOptionChoice params
At the moment the latest version only takes arrays but I think we're adding back support for both
stable doesn't, but main does
By array of string pairs, you mean an array of tuples? e.g. [ ['foo', 'bar'], ['hello', 'world'] ]
If so, we replaced those for objects a while ago. Makes sense, since choices have 3 properties, the third being name_localizations.
speaking of builders' choices, why is name_localizations snake case in there? its kinda inconsistent with the setX and addX methods, couldn't it just get transformed to snake case internally? camelcase is pretty much the standard in js
because in paython they use snake case
^ and dapi uses python
Builders are meant to build full raw data. This is why properties are snake_cased, and why nested objects also take in snake_case'd objects. Could we allow camelCase too? probably. But I feel like that would only overcomplicate the code
hasn't there been talks of like
- camelCase along with snake_case
- seperate camelCase and snake_case classes
- camelCase conversion method
and they all basically ended with too complicated and unnecessary?
not really, snake_case and camelCase are supported on most things atm
what's the URL for the new discord-api-docstypes website?
there's a new discord-api-docs website?
Well vercel ruined the surprise
But please wait till I announce it properly bc I'm still setting some things up
@outer raven@analog oyster #archive-discord-api-types-help message 
in the #archive-discord-api-types-help channel 
thats not discord-api-docs 
didn't even notice 
Will https://discord.com/developers/docs/resources/user#user-object-premium-types ever be added to d.js, the normal user flags are already there don't see why not have premium types
doesn't that require oauth2 for anything about nitro to be sent to you?
Have you checked discord-api-types?
It’s defined here: https://discord-api-types.dev/api/discord-api-types-v10/enum/UserPremiumType
I'm not sure I'm just asking
I’m pretty sure the premium type is sent in the user json can’t remember
logged in user ye, not external
API types define everything in the API, since you can use them for virtually everything in the API.
The question seemed to be specifically about d.js though, not types, and that's a difference since discord.js doesn't really handle OAuth2 data (maybe apart from the Guild.addMember or whatever it's called, but it still is a regular endpoint that just takes OAuth2 token, iirc)
https://github.com/discordjs/discord.js/blob/main/packages/discord.js/src/structures/Embed.js#L185
Is there a reason for { ...this.data } rather than just this.data?
shallow clone probably
pretty much, if we returned this.data, and someone modified the json from toJSON it would also modify the Embed props
Wouldn't editing the fields, footer, or any property that is a ds still be affected tho?
Yeah it’s a shallow clone not a deep one
Hello 🙂
I reinstalled my project with keeping the "discord.js": "^13.6.0" dep, but I had the bad surprise to see my code break. I then eventually figured out the cause was my ApplicationCommandOptionChoice usage (I was sending the old [string, string] array) + version update to 13.7.
So my question is about releasing : how a breaking change like this was only refered as a documentation update in the github release ?
(Or did I missed something)
Thx 🙂
Those are re-exported from an external dependency, @discord/builders which doesn't have a stable semver major release yet
Oh ok my bad I did not notice that
Anyway I should not have break my lock file, so it should not happen again
But I might set stricter dep constraints just in case
hm
"stable semver" refers to 1.x releases. builders is at 0.x so therefore minor updates to builders can contain breaking changes - but I'm wondering how this applies to d.js re-exporting 
in my mind this feels like it should be breaking to d.js but..
Ngl that's what I think too, but I don't know/contribute enough to complain too much about it
- with locked deps it should not break often
Hi, is there a new djs version coming anytime soon which would require rewriting your bot?
v14 is the next major version which would require you to rewrite some parts of your bot
Do you know estimate of when it will be released?
There are no ETAs, it will be released when it's ready
Uh, alright, thanks
@tacit crypt you never really suggested a better name yourself but I’m confused: do you agree with it or not?
I agree with the PR, and if a better name can be found then even better
But from my pov its really not a blocker
or it shouldn't be I should say
Alright 
Why is name separate from the options argument in GuildChannelManager#create()? Why can't it be inside the object?
required vs. optional
I mean it could be in the object as a required prop
that was the reasoning afaik
There are some inconsistencies for "required vs. optional" like embed footer text and client intents I'd say
I personally would prefer it be a single object like channel.send and such 
There is a pr ig
I looked for one but iirc it got closed
Which one?
Alright cool, 3 approving reviews
ahyes the pr with the best english
they literally state that they're having issues with english in their opening post, there is absolutely no reason to bring that up again
Someone could at least fix it, some sentences don’t make sense at all
Even if its broken english, I can read it just fine
Not sure if bug, but - You can send embed with empty message content, but if you have a message that has content and you try to edit it into embed, it will throw error that message content must be non-empty string
Are you trying to set content to an empty string, or to null?
Empty string
Try null, on latest @dev release
That works, thank you, a little confusing, but its alright I guess
Just wanted to stop by and send a big THANK YOU, from me, you guys are doing great things and made my discord dev a piece of cake
❤️
What could be causing this error? Fresh checkout of the main branch, ran yarn --immutable, yarn build, then yarn test
also
#7985 in discordjs/discord.js by memikri opened <t:1654052875:R> (review required)
feat(Client): wait for ClientReady event before resolving login
📥 npm i memikri/discord.js#feat/defer-ready-event
Shouldn’t you be using the ready event to wait for ws stuff to be ready?
Well my though here is that this makes the login() method more useful, since currently it doesn't really matter too much and its return value is useless
This also would make it much nicer to use in a top-level-await context, for example
But what if the client isn’t considered ready?
login and ready are not the same thing
Well that's what the PR would be solving
yes but I'm proposing to make them the same thing
I can't think of any compelling use-case where you would want to use the client when it is between logging-in and ready
I still disagree that we should abstract it away when users can promisify the ready event themselves easily anyway
the client should be considered logged in as soon as it identifies, which is not the same thing as being ready
You can start making API calls after being logged in but before the client is ready - its just caches that aren't populated
tbf you can make API calls without the gateway at all
Well yes, but login is the method that sets the client token
I think you can also start sending gateway opcodes before receiving ready, though not really sure on that one
wha
bots that aren't in a guild don't receive a ready event, so in those cases you only care about logging in
also
await client.login(process.env.DISCORD_TOKEN);
const [readyClient] = await once(client, 'ready');
console.log(`Logged in as ${readyClient.user.username}`);
Is pretty easy with TLA or an IIFE
client.on('ready') emits the token used to log in, not the ready client, as in your example
It doesn’t
(hence why I was calling its return value useless earlier)
No worries
I made the PR that added that type distinction so I should've known that one lol
not yet from what i know

We recently landed 13.7.0, which fixed some crashes for TiV.
Creating new PRs for v13 will just push back eventual v14 release, which is starting to get slightly overdue. The hypothetical 13.8.0 would either get delayed by multitude of new PRs for backporting / adding stuff just to squish it into a release, or it would have only a fast-tracked TiV support. Doing the latter wouldn't make that much sense, as v14 already fully supports it, and the former makes entire situation worse.
classic discord.js moment
Thats not really useful for this channel 😒
If you have a bug report, please report it on our GitHub. If it was fixed already in a newer version, update and see if the issue still happens
But this of result of the discord.js stupid version system where next version results in lower mainaonence of older when newer is still not stable
And this happens over and over
v13.7 is stable
But in result of v14 development there are many features missing
thats the point of new versions they cant add everything to 1 version if they update they make new versions
do you understand?
discord.js stupid version system
Yikes. It's semver dude, it's literally a standard
Please calm down, there's no need to rant about our versioning system
i can try explaining better
Which is how software engineering and versioning works. We have backported several pull requests from v14 to v13 (which makes this remark void), and just because this one thing is currently not available in 13.x doesn't mean we are ignoring anything 🙂
And sometimes maybe we do have bugs that we haven't encountered before. It happens
. Most helpful thing you (or anyone that encounters a bug) can do is open a GitHub issue with reproduction steps, the version you encountered the issue on and let us triage it
Problem appears when update will be released after few months of discotd support
I don't even know how you encountered that issue. Maybe your next steps should be telling us what you did / how you encountered that issue so we can look into it
maybe you don't use version 13.7
I just had an idea: What if instead of the cache storing the message object, aka the object with all the helper reply functions and such, what if it'd just store the actual data, and when an event is called or someone uses cache.get or .fetch, the lib will just construct the obj then and then return it. The idea is that that'd help with saving memory
there's a tradeoff between memory and efficiency, and that seems like it would lean way too much towards the memory side and reduce efficiency
That's raw data storage
But we won't do that way, rather, we'll have structures with a data field
this also sounds like it would only support get or has methods, and filtering or finding would mean constructing everything
As I already did some tests. Naturally you can save up to 35-50% of memory, but the effeciency is pretty bad.
On nested objects such as message.guild.me.user there is a major perfomance difference of 22ms
For instance on a test with 120k Guilds, I saved up to 7gb of ram (8.6gb vs 1.6gb; just role and guild cache)
Ah ok
That's why we're doing a hybrid
So we get most of the memory benefits, without sacrificing performance
How was it done before the data field?
like it is done currently?
wouldn't they potentially still be?
Yes but that’s with getters right
Which just get from the data prop
I’ll check
Hm is it so that the prs haven’t been pushed yet
We have an entire issue that's very elaborated on this
The issue targets TSR
Yes
Ah, I thought you meant it was done 😅
No, TSR is coming out after v14
And if it was done, the issue would have been closed
You can also the TSR milestone here https://github.com/discordjs/discord.js/milestone/13
Ah TSR = Typescript rewrite
TSR will happen sometimes after v14 btw, not necessarily a v15 (it's a massive undertaking)
what reason would something be declared in BaseXChannel as opposed to XChannel?
the base channels are abstract classes that hold common methods for that type of channel
e.g. BaseTextChannel is extended by TextChannel and NewsChannel
what about these new textchannel-like methods on voicechannel?
you can see how that was handled in the pr that added it https://github.com/discordjs/discord.js/pull/6921/files
Going to take a shot in the dark and ask here. How does one fork the main library and install from github with the new setup?
I reset a branch hard to the main lib, didn't do anything else, and it failed the 'post install' script.
Deleted that post install script from the 'scripts' in package.json and it installed but then trying to run a bot results in 'cannot find module 'discord.js'' same with 'cannot find module @discordjs/discord.js'
I am at a loss at this point on what the heck i'm supposed to do.
You can do one of the following solutions if you have the fork downloaded locally:
this doesn't help for hosted bots, unless you're assuming i have to do the same thing for each bot i host
is your bot on a VPS?
i have 3, and 2 local test bots
you can link your fork on all of the hosts
you'd clone your fork on the servers and then link to them
sounds like fun
So now i fall back on what the heck does it mean by
Use yarn link inside the packages/discord.js directory and in your application's folder.
i'm going to assume i need to create a folder and i can name it whatever the heck i want in the node_modules folder and then use link with it?
I'm not familiar with linking in yarn, but you can have the repo cloned anywhere you just need to provide the path when linking
And this is why i ask question and am dubious of any comment that doesn't specify any basic directions, assuming the reader knows everything
In discord.js' folder you run yarn link and inside of your project's you run yarn link discord.js iirc
i figured it out, it was demanding a 'name' property in package.json
and also no
yarn link just posts the 'help' for link
and of course the link did absolutely nothing
This command is run in the package folder you’d like to consume. For example if you are working on react and would like to use your local version to debug a problem in react-relay, simply run yarn link inside of the react project.
Unknown Syntax Error: Not enough positional arguments.
$ yarn link [-A,--all] [-p,--private] [-r,--relative] <destination>```
documentation is so much fun when it's invalid
which version of yarn are you using?
those docs apply to yarn 1.x, but in yarn 3.x, you just do yarn link [path to package]
so that must mean that packages/discord.js is probably already registered to some name
nvm it's 3.2.1
okay so that still doesn't do anything
the yarn version in the discord.js repo is 3.2.1
but if you didnt install it in your own folders you wont have that version
how does one acquire this
published versions of yarn only go up to 2.4.3
"this project is configured to use yarn" so i forced to use yarn now am i? this is very inuitive
The simplest way to actually get your local fork / any fork in your other repos is packing the discord.js module and installing from the pack 
^ this pretty much
well then, lets see how overly complex this solution is then
cause so far i've hit a dead wall
ERROR No matching version found for @discordjs/collection@^0.8.0-dev
The latest release of @discordjs/collection is "0.7.0".```
unless i'm stupid and this isn't what you mean by 'install from pack'
Well you'll probably also need to pack collection, install it first, then the djs pack
pretty much anything that djs uses
it also needs rest... so i suppose i ahve to do that one as well?
so can i not just pack the entire project and install from it?
or is it literally just one by one
don't think you can
fun
I mean, unless you're trying some local changes yourself, you can just install the @dev versions of our modules
i have local changes
though i do think, if i'm especially lazy, i can just upload the tgz files to github and then install them when i pull
don't we allow to configure pretty much anything already anyway
what is still missing people need a fork for
there are several changes that i have that make my life insanely easier
plus i've found several interesting bugs that are so much fun to diagnose
maybe they were already found and i needed to simply update my fork
but then i fall back to 'i have several changes that make my life easier'
also
installed collection
tried to install rest, said collection doesn't exist
:D
yeah I honestly don't know if its even easily possible
that's 4 hours of my life i'm not getting back, fantastic
Can you try it with npm instead?
keeps posting this error:
Yeah because we use the workspace protocol
If djs used yarn v1 you could link packages in the monorepo with themselves but in v3 they removed that possibility
Never really understood why djs moved to v3 tbh, it doesn’t give any benefit
It does, many of them, including performance and plugins (which we use)
which plugins
have you thought of looking at the .yarn/plugins dir
Also v1 is purely in maintenance mode lol
thanks...? I was telling Rodry to have a look at it
dont worry i looked and i sent
but the question wasn't literally asking "what's in there", but was in form of "did you try looking there yourself before you complain that we moved to newer version"
ok
Judging from all the activity on github it would seem like v14 is close, is that right?
no eta
it's ready when it's ready ™️
probably no
Are we gonna have another v13 release for the zombie connection pr?
looks like it
@dawn merlin seeing as you made a PR to remove a feature I added could you let me comment on it please
Seems like APIAttachment doesn't include the property name, making it impossible to use the AttachmentBuilder and give the attachment a name, could someone fix this?
not sure if the issue is in dapi types or djs
can't commit due to this, what should I do?
run yarn build
right yeah that fixed it
https://github.com/discordjs/discord.js/pull/8016 turns out the fix was easier than I thought so here it is
might as well fix the other error too
files?: (BufferResolvable | Stream | JSONEncodable<APIAttachment> | Attachment | AttachmentBuilder)[]; in all places is missing AttachmentPayload
which didnt allow you to construct an attachment with files: [{ name: 'some_name.txt', attachment: Buffer.from(xyz, 'utf-8') }]
will add that
But tiv is out
that's not what i'm asking
We usually wait yes
But if discord is too lazy to merge stuff that won’t change because it’s a live deploy
We usually don’t care
kk
webhook messages shouldn't be cached if the bot can't see them right? (i.e. send through WebhookClient)
i suppose there isnt much of a reason to cache them no
Seems like v13.8.0 added a breaking change, was this intentional?
Probably not
@vernal rose I don’t think we can use cliff jumper here
We don’t want or need any of its features
Yeah just closed the pr then got your message xD
Is this just a type issue
Or smth
Well I assume the event was always emitting a channel with a thread manager, so receiving a message in a voice channel will break things, as you didn't need to check if a thread manager existed before
It isn’t, it’s actually breaking because voice channels indeed do not have threads
True ig
I guess it’s a compromise we shouldn’t make, but we didn’t want a v13.8 in the first place
It’s risky to update, but I think for those who really want to stay on 13 worth the risk
If v14 is near it could’ve just been released then but idk if it is
It’s not
Builders needs a rework
Permissions 2 isn’t merged
Neither is the object input one
Which are all breaking
is automod also breaking
havent checked if that breaks anything for whatever reason
If no one backports it
rephrased
Right, idk didn’t look yet
meant "is it breaking so it needs to be in 14.0.0"
so like, does it block v14
icic
So far that one is a minor
Don't think anything will be breaking in it
They change that PR a lot though
how is the caching logic even supposed to work? If the bot can indeed see the channel where its' own webhook message was send it gets two requests for trying to add to cache, one from returning the API request from and one from the bot actually being in that channel, if the bot tries to parse the APIMessage it crashes because it doesn't have the guild_id field at all (and this.chanels to resolve)
can i just PR a revert for the webhook APIMessage -> Message returns and not try to add it to cache like before? 7917 causes webhooks to break entirely cause of ^
#8031 in discordjs/discord.js by Rygent opened <t:1654568058:R>
An error occurred while sending the webhook message
Yeah it’s either reverting that PR or making the channel getter on a message nullable
well it's not really nullable, it's just that the getter incorrectly assumes client to not be a WebhookClient so the channelmanager doesn't exist to resolve from
yeah but it even if the Webhook client had a channel manager it would be null, so it also returns null for regular clients if your bot isn't in a guild (which is misleading).
probably better to return APIMessage then yeah
same thing applies when returning the message, it could never add it to cache because this.client is a WebhookClient so it always returns APIMessage
Serious question: Are the localized commands working?
Because I add them with the edit function, but when I refresh my cache and fetch the commands again, the localizedName and localizedDescription properties shows up as null
From what I'm reading in the Discord API documentation, these fields are not sent unless the client requests them (using the withLocalizations option of the fetch method), but this method only returns the fields to me if I have previously used the method edit (or create) to add those fields. But if the cache disappears (for example, by restarting the bot), they return to null on fetch
What is the point of being able to add these fields, if they cannot be obtained later?
already was
just poorly typed
(technically not possible, but ya never know)
From what I'm seeing, there seems to be a build override for localizations for three months now, so this feature is still under development. Why is it supported in the stable version of Discord.js? Why don't even the API docs warn about it?
the API hasn't changed idk why it isn't on stable discord yet but it works as-is, no warning needed
Localization is already available for commands to set in advance, the client support is supposedly coming sooner than later
That is, localizations can be sent, but not retrieved from a bot client?
Localizations can be set but your client won't render them
You mean, on a user client (in the graphic interface)?
The client we all use to interact with Discord
Localised application commands are still an experiment, so everyone sees what's on name and description
There's the thing. Because I had been trying to understand for a long time why I couldn't fetch the locations of a command, if according to the API documentation it is not an experiment (https://discord.com/developers/docs/interactions/application-commands#retrieving-localized-commands), and the stable version of Discord.js is prepared for this (https://discord.js.org/#/docs/discord.js/main/typedef/FetchApplicationCommandOptions)
Client and API are two different things
We simply support everything the API supports
But what the Discord Client supports, is up to Discord, it has its own milestones and stuff
But if in not mistaken, what you're saying is that when you fetch commands, via the API in discord.js, you don't get the localisations back in the command object?
have directory channels been released publicly on the API? I saw them on 13.8 for some reason
invites can point to them
They're part of school hubs iirc
Directory channels have been documented for a few months now
You do if you have the query param set
@white hedge were you setting that when fetching?
Yes, with const guildCommands = await someGuild.commands.fetch({ withLocalizations: true }); (using v13.8.0)
will they be accessible to the public in regular guilds?
A directory channel is a channel containing guilds within a student hub
So a student hub is all you will ever find it in
Yes, i get null on the localizations (both nameLocalizations and descriptionLocalizations), but only BEFORE editing/creating the command to adding those fields. When I create/edit the commands, both fields are correctly defined when I fetch them again with that parm set (i suppose because it's on cache)
where can i find a minifed version of discord.js
why
Ill just leave this here, in case others haven't seen it and want to give their piece: https://github.com/discordjs/discord.js/issues/8015
I think Collection#find() and other methods that take functions as arguments should have better errors.
Like if you provide a non-function to .find(), it seems to throw this error: https://sourceb.in/zh5x7UeCs6
but I believe it could be better, like fn provided for Collection#find() must be a function, received ${typeof fn}
I believe running node with --enable-source-maps is what you're after? Also it doesn't error for me. Just ran <Collection>.find(3) and it returned undefined
that's weird
neither of these seem to have anything checking if it's a function:
https://github.com/discordjs/discord.js/blob/main/packages/collection/src/index.ts#L240
https://github.com/discordjs/collection/blob/main/src/index.ts#L232
cant replicate
maybe you did it on an empty collection
Ah okay, let me try with something populated
Same error as above
This boils down to what I said at the beginning, you want the --enable-source-maps option when you start your node
i was not using source maps
I am unsure if we want that
The documentation states that it is identical to array.find
That does take a function too
Did you get that error by providing two arguments? First being not a function and second being whatever?
Because then it’s the fn.bind that produces that error
Actually, it wasn't me who got it, but I thought I remembered getting that error before for that reason, and the person who got that error said that the problem was providing a non-function to .find()
They tried .cache.find("name")
Well as you can see, we're not getting that error... you probably should have tried that yourself too :P
That usually only happens when you either don't know js, or follow a tutorial thats rather outdated
when I did try it I had the same error as you, but idk, maybe they had an old version ¯_(ツ)_/¯
Someone made https://github.com/discordjs/discord.js/pull/8064
This is related to this issue but not a fix for their issue. The error @mighty bough was getting was coming from a minified version of collection. But that pr makes collection.find identical to array.find
https://github.com/discordjs/discord.js/pull/7204
Why is this inactive?
that's a fairly difficult question to answer, lol
if what you're wondering is if it's been dropped, the answer is no
it's a p big undertaking and some things just need to get ironed out before its completed
I believe it's also waiting on /ws?
Partly, yes, I have something in mind, but I have finals to take care of first
Why is the api for awaitModalSubmit not so user friendly? Why does it throw instead of returning a empty value when nothing was collected? You're forced to catch the error and you can't even compare against it properly because there is no instance of the error exported
Seems like you can compare against it, but still weird it doesn't return a empty value like previous collectors did
Nvm the error instance is not exported so you can't compare
wdym? non of the await* returns empty value after timeout.
👎 empty value is just poor behavior here IMO
albeit the error not being exported is not ideal either, will look into that in a bit if no one else gets to it by then
agree. Error can give u more info then a empty value and u can always add a catch to return empty value
Collectors used to
But you could also control what throws an error in there through the errors property..
yeah I see, errors being unexported is more of a library-wide problem
@solemn oyster would there actually be any concerns in exporting from src/errors?
it's a start but it actually wouldn't fully solve the issue lol.
this[kCode] = key; the error codes are locked behind a symbol so they'd still have to check against the .message
yeahhh this feels p hard to fix without an overhaul of how errors are handled honestly 
What if you made a code getter?
Or replaced the symbol property with a regular one
that'd be a bit better I suppose, except our codes are just hard coded strings
e.g. in this case for the await modal thing
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
they'd need to js } catch (error) { if (error instance of DjsError && error.code === 'INTERACTION_COLLECTOR_ERROR') { // do things } }
which is less than ideal
could honestly fit in something that redos errors in v14
There is a getter for that
is there
im tired
may have missed it
oh, yes
get code() {
return this[kCode];
}```
I see I see
👍 will make a PR about this tomorrow, all though it'll probably be another 500 lines changed like my last one as I attempt to rewrite this mess 

Pls ping me with the pr link if u don't forget
@oak quail What's the progress with https://github.com/discordjs/discord.js/pull/8050?
oh right
i won’t be home for a while but i can add the note on sunday
is there any syntax or should i just add text to it
I'm unaware if there's any syntax for it, since it's wrapped into a table, so possibly plain text nvm, thanks ckohen 
warn blocks work in typedefs and parameter tables
#8068 in discordjs/discord.js by didinele opened <t:1654937933:R> (review required)
refactor: errors
📥 npm i didinele/discord.js#refactor/errors
^
hm
yeah nvm, this should solve most issues
from here on out the only improvements we can make is make our errors more specific
e.g. INTERACTION_COLLECTOR_ERROR is used basically everywhere
it's hard to get much out of it sometimes
ty
@ruby terrace on #8065 why are there two awaits on this line? Are you awaiting a sort?
appears so
that doesn't do much does it
absolutely nothing indeed
if I had to guess ckohen wrote await readdir(handlersDirectory) and then added .sort and just hit enter on the VSCode suggestion
which seems to always add another await in front since it doesn't check the methods' return type or something
is interaction.options.getFocused().value meant to have all these possible types?
how can it be a boolean and undefined?
what type are you expecting?
just string and number
you can't have autocomplete on boolean options
and I don't understand how it can be undefined
is this v14
yes
hmm
yeah, good catch
export type AutocompleteOption = Pick<CommandInteractionOption, 'name' | 'type' | 'value' | 'focused'>;
it just keeps the value from CommandInteractionOption
where that type is accurate
not sure what this CommandInteractionOption interface is meant to represent tbh
an interaction option.
I don't think it's supposed to have boolean or undefined actually for a autocomplete interaction
anyway, if you wanna, feel free to PR a fix to the typings
otherwise I'll do it in like 2hours
no boolean there through
but what should I do about the undefined?
that's because they're dumb
do i just overwrite it in the autocomplete type?
which they?
discord
discord
oh, makes sense
- export type AutocompleteOption = Pick<CommandInteractionOption, 'name' | 'type' | 'value' | 'focused'>;
+ export type AutocompleteOption = Pick<CommandInteractionOption, 'name' | 'type' | 'focused'> & { value: string | number };```
Thank you
decided to go with this so as to fix the focused type and make type more accurate
lgtm
Fine to me too
@outer raven ok hear me out
hm
Are you sure its safe to remove the cacheType?
I guess so
But
I think its be better if you still use Pick syntax
oh
And just overwrite it with & or something
I didn't realize that but in this case I don't think it makes a difference
like don't pick out certain things and then just do & { type: <type>, value: <stype> }
that's only relevant for options with resolved properties like members or users
might be better for not having all standalone types yknow
if I keep Pick I'd only be picking name
I can change it if you want but it really doesn't make much of a difference
should I?
That's true, but
What if they ever extend it in some way
I think itd be less of change for us then
coolio
ty
It also probably makes for better code consistency
And generally good practice
Also please, for the TSR rewrite, you wanted to have getters to builders right (for v14)?
would be nice yeah
Is there any compromise we could find where you still somewhat get what you want to achieve, so you do your mutations with some sort of structure
but not builders directly
🤔
well Siris suggested an update method a while back which would only modify the passed properties and leave the others untouched
Would that be on builders or djs?
on builders
but if we go with that idk if the set methods would continue to make sense
yeah true
btw I pushed this
I'd be fine with possibly having an updateX method if the need is there, but the set methods should not be removed at all
yeah that sounds good
updateX or update in general
because then wed just duplicate the set methods no?
lol
but without clearing
well, update makes sense only for nested objects
oh yeah you can just have 1 update method that works for all
but wouldn't that be a lot of methods
how so?
well instead of 1 update method for the entire builder you'd be making 1 for each object
updateAuthor/setAuthor
updateFooter/setFooter
updateImage/setImage
setURL
setColor
setDescription
...etc
and for embeds for example that's a lot
Embeds have only... 4? nested objects
Yeah its not that much
Sure, if we duplicate all set methods
But thats not what vlad is saying
I dunno, a global update method then brings the question for a global set method, which would really not help with the consistent interface argument of the RFC
we could probably bring in those update methods before the RFC rewrite proposal
since theyd be minor
a global set method would just be a new builder instance, no point in doing that imo
i'd say this is an alright interface, supports both use cases, and is distinct enough
im fine with both tbh
Possibly, yea
@analog oyster @opaque vessel did yall delete your comments on the PR?
yeah, it doesnt really make a difference
the name doesn't but the type kinda does
we were just talking about the focused prop
ye ik
Yeah it's fine to make that true 😅
i pushed a commit to make it true
can you rename the type then
no?
its kind of misleading, because not all autocomplete options have focused: true
the type is only being used in getFocused(), but still
if in the future that type is needed, it doesnt represent any autocomplete option
just focused ones
all received autocomplete options do have focused set to true
when you receive an autocomplete interaction you only have 1 option which is the focused one
i just tested this btw
idk how else to put it, that type now represents focused autocomplete options
You should be getting all provided options..
im not talking solely about autocomplete interactions
I was replying to this
i was continuing this
on an autocomplete interaction you dont
That's..not true, the API definitely gives all options
vlad I just tested this
If you have a user option then an autocompletable string option and you fill in the user one first, you'll get it (or SHOULD get it)
API doesn't send any resolved data, just those in AutocompleteOption
You won't
I recall this bc I also tested that 
ok lemme do a different test then
That's why those getUser() etc. methods were removed from the typings on an autocomplete interaction, because there was nothing to resolve them against
The fact its not resolved is one thing
you should still be getting the option
Even if not resolved
At least that's how I remember it 
If you have an autocomplete option, for some reason, Discord just doesn't send anything else but it
It'll send the user id, sure, but not the user object
Yeah
Phew, thought that changed too
so you get all the options you've filled up already and not any resolved data
get('user_option').value would get the id but unfortunately no user object
i was getting confused because I thought you were saying you would get options that weren't filled
also interesting how they send a number as a string 🤔
That makes sense to a degree
so would value always be a string?
Since you can type anything in the autocomplete, for instance searching case numbers by reason
Although it is definitely concerning then because even in -types it would be wrongly typed
ok so ill rename it and make it always a string
do you have this interface in -types?
It's probably only a string in autocomplete scenarios
as shown here
alright hope thats the last commit to that PR
Uhhh..yeah its in -types to a level... 
Isn't the integer here a number? So the value is a number?
It just seems only floats are sent across as strings, right?
If autocompletes are always sent as strings, I have some painful types to fix
But doesn't that screenshot show a number or am I tripping
@outer raven poke poke^ x:
Oh
Omg lol
........so autocompletes have the value as string...Le fuck
Should be easy to fix tho in -types
union all the things
yes
my code checks if an option's value is a number sometimes, I wonder how I never noticed that break
oh wait turns out it only checks if it's a string, thats funny
I never noticed this because I never used autocomplete for numbers... yay we caught it
Same... lol
when they first got introduced i went
on that, but it makes a ton of sense, bc it's essentially an enum/id you are selecting, with some verbose name as label
ID? 🤨
yes? int ids exist, not everything is snowflakes, fam
there are multiple reasons why you wouldn't want to represent a... idk, job, in an RPG?... as a string, but rather with a job id
Autocompletes can be used to also search
yes, and numerical ids can make sense there, because you can assign a label to it
i could, for example, give every tag in /tags a number instead of using a string to identify it, making it a worthwhile use case for autocomplete numbers
@outer raven can you update the AutocompleteOption JSDoc too?
Renaming it and removing the number type from the value
will do
done
should probably backport this to v13 right?
I don't believe we are doing another 13.x
What dd said, doesn’t exactly hurt anything so whatev
i heard that for the last two 13.x's so you never know
and there's 1 PR for v13
That one would be a patch though, not minor version (if even merged)

Don’t call me out like that
lmaoo sorry sorry
but is this the last last one?
like qjuh said it could just be a patch
Idk
We can do another 13 probably
The first time I said it was only because the release setup was a pain
But I fixed that
The 2nd time was because I thought v14 will be ready and TiV will be a pain to back port
Turns out neither happened
And TiV was easy
then ill open the backport pr once that is merged
You can open it now
And just fork or base it on that branch
So checkout that prs branch
Make a new branch from that
And work from there
¯_(ツ)_/¯
Just make sure it’s your fork
Not the persons fork
i usually checkout main and just cherry-pick lol
which is why i wait for it to be merged
its quite easy
Are typings missing here?
I don't see .setDefaultMemberPermissions / dm which is in the docs :/
Nvm seems like it was added yesterday so got to wait for a new release
its actually on the SlashCommandBuilder
Shouldn't it be available through ApplicationCommandData or something similar as well?
Idk I just prefer to have regular objects to create commands, maybe I'm missing some type here
We can’t add such methods to regular objects. We add them to specialized classes
You can see from the typings that it’s just a type, not a class or anything usable by js
What about a property then? Like currently I added those manually but they could be added natively and the same method would be called for them to actually apply?
How do you suggest we do such thing?
Well defaultPermissions is a property already
So there would be new defaultMember and defaultDMPermissions properties
defaultMemberPermissions is alr on ApplicationCommandBase
I don't see it 🤔
Or let me check, I realized ur showing ur own typing
Yup
If I can add some reference to anything that has it to make it work it's all good, but currently I see no way of achieving this
It’s on v14 dev
Okay then I did see it correctly, ty for checking 😩
No backports to v13 atm
I guess I can use the dev version since this bot isn't live
if i'm not misunderstanding anything, you want
/**
*
*/
method(){}
/**
*
*/
method(){}
/**
*
*/
method(){}
```right? The way you're doing it, send gets the last documentation, which is for editMessage
try this out
class BaseClass {
/**
* Send message
*/
send() {}
/**
* Fetch message
*/
fetchMessage() {}
/**
* Edit message
*/
editMessage() {}
}
class ExtendedClass extends BaseClass {
/**
* Sends a message with this webhook.
* @param {string|MessagePayload|InteractionReplyOptions} options The content for the reply
* @returns {Promise<Message>}
*/
/**
* Gets a message that was sent by this webhook.
* @param {Snowflake|'@original'} message The id of the message to fetch
* @returns {Promise<Message>} Returns the message sent by this webhook
*/
/**
* Edits a message that was sent by this webhook.
* @param {MessageResolvable|'@original'} message The message to edit
* @param {string|MessagePayload|WebhookEditMessageOptions} options The options to provide
* @returns {Promise<Message>} Returns the message edited by this webhook
*/
send() {}
fetchMessage() {}
editMessage() {}
}
```Hover above send then fetchMessage
hopefully this clears the confusion
i think i know what you mean by seeing something similar, you probably saw some seemingly out of place jsdocs and misunderstood what they were doing
i'll see if i can get an actual example
@outer raven and anyone else, we'll make a 13.8.1 release (patch) so if there's any other fixes you want making to there, can do
alright thanks! Will open the backport for that PR
@tacit crypt to resolve https://github.com/discordjs/discord.js/pull/8074#discussion_r895155705, I've 2 choices either use .setValidationEnabled when defining predicate or just before using .parse. Which one you'd like? If we use it just before .parse, then a user will be able to disable validation at run time.
its not too late to just move to json. builders are way too complicated
I personally agree. But we still support JSON everywhere anyway (it's literally what builders build for you) so this is just an unhelpful snide remark and not constructive discussion at all
Nobody is making you use builders
But we still support JSON everywhere anyway (it's literally what builders build for you)
that's what they should be doing (like Embed in v13), but they also do validation which is part of the "too complicated" remark.
Nobody is making you use builders
I'm not, not sure what that has to do with anything lol. I doubt any of the maintainers (people making all of the massive changes) use builders' structures either which is definitely another problem (feel free to correct me if im wrong here)
I also agreed with just about everything u said on the rfc, just haven't posted on it
This message before yours was about disabling the validation on a single unified builder structure rather than having the Unsafe* separation.
As for usage of builder by maintainers I don't know enough to comment - I don't use builders myself
The fact that they validate the input isn't a problem for me, and for what it's worth I think the slash command builders are excellent. Immutability lends itself well to that scenario. It's all the others that are the problem 😄
I certainly do, I have a package that exclusively uses builders for paginating embeds. Most if not all of the embeds I use are from builders, components is a mixed bag for me. I also don’t think I’m wrong in saying Vlad uses them heavily too.
yeah true 👍
I switched from builders (v13 style) to json and Embed is a perfect example of a structure that can be done the exact same - or even easier - with json. Components are also very easy.
Is there a particular advantage you feel you get out of using them or is it just stylistic?
Personally it’s out of habit
I don’t think one is objectively easier than the other though
As for the immutability that’s less of a builders issue and more of djs one. Djs controls the cache and decides how components are cached within messages
Im not asking to mutate cache
Even if builders wasn’t a separate package I still would’ve made that PR
Then what are you asking to do?
the idea of having to convert a component to json to convert it to a mutable component seems very contrived to me personally.
or even if you don't convert it to json manually it still gets converted to json
A component or a component builder?
from monbrey's example in the rfc
ButtonComponent.from(theData).setDisabled()
I need more context here, where is theData from
I don't think it really matters tbh (it's just really complicated for changing a property on an object). You could replace that line with
theData.disabled = true
if you were using just json objects
however I do have an example:
In one of my bot's commands, it sends a message (using interaction.editReply, which apparently always sends a Message object now?) and after a collector ran and the message has been updated (dynamically adding/removing/modifying components), I want to resend its components but disable them so they can't be re-used after the command is over.
message.components returns an ActionRow structure where I can access components and whatnot, but I can't edit them. I could recreate the component using ActionRowBuilder.from, but the data would already be converted to json regardless and I could just as easily modify it directly. I think the example in the pics are equal (taking the first component of a message, setting every subcomponent to disabled) and as you can see the 2nd one is quite a bit more complicated - while also getting "worse" typings.
If you have 5x5 grid of buttons and you want to disable the one right in the centre, how would you do that using builders?
This way still edits a property of the nested action row components directly, which is supposed to be against the design of builders anyway I would have thought
e.g. if r.data is private, you're shit outta luck
apparently the .data isn't private, the example was done in ts (modifying my actual code). However idk the design of builders and it might be against every design input lol
Factory functions; if you’re generating 25 buttons I doubt you’re making them all statically. Make a function that takes state as an input (Map) and returns component as an output. When you receive a component update the map and call the same factory again. Components shouldn’t be responsible for encoding state. An array of action rows isn’t a replacement for map-like structure. This is true for both json and builders
That sounds horribly inefficient to have to use the factory over and over again
I already have a set of 25 validated buttons, why cant they be reused
Maybe to give a real world example, I've seen implementations of tic-tac-toe with buttons where the label gets updated with an X or O based on position
You’d be doing the same thing after every interaction anyways. You’ll always construct a new builder
Well no, I wouldnt
Then how can you be sure state doesn’t carry over between interactions between different users?
I'm not understanding the question
I’m saying you always have to reinit state whenever a new interaction comes in, or else you end up using the same state for all users invoking a given interaction
Why would the state have changed
If two users are playing tic tac toe I can’t allow them to use the same components in the same state
Two separate games*
Would those two states not be in separate scopes of execution?
Sure but they both need to created separately, right?
But you can’t modify cache in place, you always need to recreate the component with .from
Yeah if you use builders
Well the api returns immutable structures so it would be a similar story with json
But you'd already have your JSON that you used to send them in the first place, and it's mutable. I don't care what the API gave me
Hell you could even make that JSON using builders if you really wanted to, and then edit an individual property in it as needed
Yeah the json still needs to be created every time, other than validation you’re not really saving much construction cost.
read this again, and you'll understand what we're saying
No I dont
ckohen who was that directed towards?
you
...no it doesn't. What am I not explaining properly.
const ttt = [array of rows of buttons in JSON];
const game = await interaction.reply({ components: [ttt] });
const collector = game.createMessageComponentCollector(options);
collector.on('collect', b => {
// b.customId shows that the middle button was clicked
ttt[1].components[1].label = "❌";
ttt[1].components[1].disabled = true;
b.update({ components: [ttt] });
});```
I do not need to recreate that JSON
It exists in a scope where its mutable per event received by the collector, but out of scope of any other interactions that may have started games
If you know the exact component index why not keep a reference to the builder variable and just mutate that then?
Because isnt it supposed to be private?
Hidden away behind builder methods?
And if its isnt whats the point of the builder?
No if you know what component in the actionrow changes every single time, why not just keep a reference to the builder?
mutating specific field indexes is incredibly difficult with builders
The component is known since the index is hardcoded
And modify it how? spliceComponents?
so RowBuilder.components[1].setDisabled()
I thought they were also private
Or .data.components I guess?
We're back to data being a public property again then
You already know what component 1 is beforehand. Keep a reference to that component builder. Place that reference into the action row builder. When the collector is invoked use the cached component reference and call .setDisabled.
Yup I agree
That would currently be possible, how would that still work if it changes to the row.addButton(button => style to align with slash commands?
I have no clue
I realise now we may have been approaching this with entirely different states of builders in mind
Apologies 😄
all good
you could store a reference to that too, but you're storing so many references now
when maybe only one of them needs to be updated
If you have a lot of references to keep track of intuitively a map is a good option for keep track of a bunch of references.
customid -> component reference
Also memory is quite meaningless here when we’re taking about n <= 25 and it’s GC’d after the full interaction lifecycle completes
*when the GC works
I don’t see why it wouldn’t here
It’s scoped to anything in the interaction block. That’s like saying you shouldn’t allocate anything in an interaction event handler bc GC may not work(?)
If it didn’t work memory leaks galore
naw its just slow, in my use cases its not a problem
Deallocing a tiny map (of mapped references) shouldn’t be slow enough for like 98% of people to notice. There’s probably structures being dealloced that take more cpu time
Let me give you an example for an embed quickly (doesn't apply currently because the builder doesn't follow the same structure)
const fields: EmbedFieldBuilder[] = []
const embed = new EmbedBuilder().setTitle('An embed');
for (let i = 0; i < 15; i++) {
embed.addField(field => {
fields.push(field);
field.setName('Name').setValue(`Field ${i}`);
}
}
// Somewhere else, after getting an event
fields[someIndexFromEvent].setName('Name (Winner)');
vs
const embed: APIEmbed = {
title: 'An embed',
fields: [],
}
for (let i = 0; i < 15; i++) {
embed.fields.push({ name: 'Name', value: `Field ${i}` })
}
// Somewhere else, after getting an event
embed.fields[someIndexFromEvent].name += ' (Winner)';
In example two, I do not need to lookup the current value of the name in order to append to it, only have the overhead of storing the json object (not classes each containing their own json object), and its easier to index into
this is quite easy to solve store the field builders in an array, set the fields to that array. On the event being recieved go the index in the cached array and change the title.
that's basically identical to what I just did
heck I could even use the toJSON() output from the builder in 1 and use the same last line from 2, but then I lose the validation
In your example you don’t assign the fields to the embed directly you add them all one by one
I don’t see the issue, you’ll always know the name(s) beforehand since you create the array with said names attached to each element. And it’s logical to assume these “names” would be in the same indices as the as the field builder.
but that's exactly why its frustrating for people
another frustrating thing:
now imagine you're doing this over time and not in the same scope. Instead of storing just an embed object / builder, i have to pass around all these extra things to wherever I'm storing them
Alternatively you can look up the index off the received message embed and look for the already existing name string
I will reiterate a point I’ve made many times. Message components are not suited for encoding state, state should be stored in proper data structures by the bot
i'm not storing it in a message component, i'm storing it in a Map (Map<number, APIEmbed> currently), but your way would suggest using that same map and shoving everything that I might potentially need into an object that contains references to every nested builder in addition to the top level one
Huh? In the example you just need the array of field builders that’s it
I need the embed itself too
why?
to use it in edit or send or whatever
they’re references you change the field in one place they change anywhere they’re referenced
I know
you don’t need the embed
then how do I resend it
you edit the field and resend
but I don't have a reference to the embed
Exactly you don’t need one
The embed you started with is referencing the field you’re editing
You just need the field
but if I only store the fields in that map, I don't have the reference to the original embed anymore
It still will be edited when it’s resent bc the embed you lost the reference to is still referring to the field you’re editing
then how does .edit() know what embed I want to send
remember, we're in a completely separate block scope here, that's the point of using the map, to transport these things between scopes over time
When edit is called you need the embed itself regardless if you use json or a builder. I’m saying for editing a field locally it’s not necessary just like it wouldn’t necessary in json
if you’re using json an lose a reference to an embed then obviously you can’t send it
right, but the map is just storing the entire embed, and map.get(id).fields[x] etc... works great
why is a map being used instead of an array of fields?
its a map of embeds
why embeds?
so you've lost the context for this conversation?
In the example there’s only one embed
now imagine you're doing this over time and not in the same scope. Instead of storing just an embed object / builder, i have to pass around all these extra things to wherever I'm storing them
so over time we have multiple
lets just say the map is on globalThis for this example
In this map what are you trying to edit on each embed?
unknown, may be every field, may be a single field, may be add a field
I honestly don't know how we could solve this in builders without exposing data which defeats the purpose, maybe getters for only things that can have nested builders
ok the solution of keeping a reference to only the fields still works here
You edit the fields in place
here, simplified so og scope: makes embed and fields, sends, separate scope: edits fields then edits message
Is this separate scope within the og scope
Ok then this is just a factory function problem. Have a function that takes abstract state and outputs an embed.
This function can even take in the recieved embed as input to represent updated state
Let me try to make the point clear: yes, we can find ways to do what we want with builders, and the best part is validation. However, doing so seems arbitrarily hard sometimes, attempting to find workarounds for problems we encounter. Unfortunately, discovering and implementing these workarounds is trumped by the ease of simply using JSON instead. I.e. storing all the nested builders works, great. I didn't think of doing that because its not exactly intuitive, and it still seems like I lose flexibility with it, so give up and use JSON. Thought process goes: I lost runtime validation, oh well, haven't had issues with it before.
Json has always been more flexible even with v13 builders, and it always will be.
The goal I imagine would be to make it feel easy to use builders over JSON
That’s why json isn’t validated and builders are. It’s also why you can pass in colors and emoji as just strings in builders and you can’t do that with pure json. People value certain things over other things and builders may be more useful to them. Others may find json much more useful.
Personally speaking I don’t think the goal of builders was to obsolete the use of JSON
But if i'm using builders, I don't feel like I should have incentive to stop using it ever
whereas currently when I start using it took all of 3 minutes to decide to stop
Let’s reverse that statement, if I’m using json I don’t feel like I should have incentive to stop using it. And to be clear I feel like giving up on something after a mere three minutes doesn’t really show an honest effort to adapt to changes.
I don't think so either, there's always going to be reasons to use raw JSON, but I don't think a reason should ever be "because builders were to hard to use" or "because builders don't offer a way to do X"
Some people think the the more raw nature of json makes them harder to use
Anyways it’s 2:20am and I need to get up at 8am so gn
this was a from scratch project, not an adaptation, 3 minutes was an exaggeration, but after thinking through the logic I determined I couldn't do what I wanted with builders
@wild flax @tacit crypt Hi I am Voxelli @fervent walrus [github:legendhimslef] using this id cuz older one has some issues,
I think we need to have 13.8.1 as soon as possible as the code on 13.8.0 resets sessionId on close which causes new identifies. This has been patched in my latest pr. || sorry for ping it was kinda urgent I think cuz there is a chance that this will cause some users to exhaust all their login quota ie 1000 per day||
Ill get the backport ready for main [main does not have any sessionId issues]
I think this was mainly affecting bots with 20-30+ shards on 13.8.0.
Yep
Every 20-40 minutes some shard is reconnecting with new session
the new patch would fix this

did you have your token get reset?
No
Can you give link to your pr?
@leaden obsidian 👀
patched one?
or the one which got merged with 13.8.0
It
patched: https://github.com/discordjs/discord.js/pull/8082 [13.8.1] hopefully
Thank you
yes you can use this code and hopefully everything will be fine
idk why I never noticed this until now. My bot with 34 shards never ran out of logins per day maybe cuz of traditional sharding? but for internal sharding peeps it caused some reconnect issues [only for huge bots]
I noticed this after updating to 13.8.0
looks like d.js is adding webhooks to the user cache now; is that intended?
It was, but there’s a PR to revert it now
@tacit crypt u said enableValidators should set setValidationEnabled to all the predicate (if I've understood correctly then u mean import all the assertion predicates in validation file and use setValidationEnabled on them right?) and not just before parsing but how that'll work? https://github.com/sapphiredev/shapeshift/blob/a23d15f533a234a59af54a9ed60bec778f069af8/src/validators/BaseValidator.ts#L80 here everytime we run setValidationEnabled, it makes a clone so if i add setValidationEnabled(false) on a predicate inside of enableValidators, it won't change the already present predicate
omg thanks 

