#development

1 messages Β· Page 206 of 1

quartz kindle
#

if you know c++ you know 90% of c

wheat mesa
#

This all looks incredibly unsafe though, writing code like this is how you get security vulnerabilities, especially in a lang like C

wheat mesa
#

C is just C++ without classes and templates

sharp geyser
#

in 1994 everything was a security vuln

quartz kindle
#

especially at microsoft

sharp geyser
#

lol

wheat mesa
#

Tbf almost all of the stdlib functions are considered unsafe now

#

strcpy is unsafe

sharp geyser
#

you guys ready for cargo js? the new rust like package manager

wheat mesa
#

Now you’re meant to use strncpy

#

Pretty much everything that expected the null terminator is now considered unsafe since you could corrupt the heap so easily

#

Null terminator was a poor design choice for storing strings

quartz kindle
#

indeed

#

delimiter based designs have a lot of problems

wheat mesa
#

Not to mention the extra cost of even just counting the length of a C string

quartz kindle
#

you lose the ability to use a specific character in the data, so you need to watch/check for that, and if for some reason that character gets corrupted you're screwwed

wheat mesa
#

Have to loop over every char

sharp geyser
#

honestly maybe I should never touch C

#

it sounds annoying

#

My anger problems that are already fueled by programming would burst through the roof

quartz kindle
#

its cool for simple and small things, but i wouldnt use it for anything remotely complex

ionic schooner
#

I'm in need of an SMTP service/server what would you guys suggest?

sharp geyser
#

like sending emails?

quartz kindle
#

like for email?

sharp geyser
#

beat ya to it

#

😏

wheat mesa
ionic schooner
quartz kindle
#

lmao

sharp geyser
ionic schooner
wheat mesa
#

I’m in the boat that the stdlib of a language should be small, but C takes β€œsmall” to a new level

ionic schooner
#

get gamered

quartz kindle
sharp geyser
#

cap

sharp geyser
# ionic schooner Yes

well how many emails are you trying to send, and are you looking for something "free"?

quartz kindle
#

anything email related i'd go for a dedicated service like zoho

sharp geyser
#

if you aren't sending a whole lot bun introduced me to https://mailersend.com

MailerSend

Start sending emails with our top-rated service. Sign up for free now to streamline your email sending process with API or SMTP.

quartz kindle
#

email is too annoying to deal with

sharp geyser
#

they are fairly cheap as well if you want to go for something paid

#

zoho I use for recieving emails

ionic schooner
sharp geyser
#

mailer send is what i'd use then

#

its easy to set up

ionic schooner
#

Roger that hoss, thanks

sharp geyser
#

and if you don't care about getting emails in return its perfect

quartz kindle
#

hoss

sharp geyser
#

if you want to get emails as well tho you can set up zoho for that

#

it's what we currently do

ionic schooner
#

Yeah not to worried for returns as its mainly going to be used for ory stuff. which is auth

sharp geyser
#

Mailer send for programatically sending emails, zoho for receiving/sending business emails

#

Keep in mind, if you are using rust to send the emails gl

#

I couldn't figure it out so I had to use the api

#

which is limited

ionic schooner
#

lmaoo yeah thats for someone else in the team to figure out lmaoo

sharp geyser
#

kekw

#

what you working on if I dont mind asking

#

if its top secret then tell me to shut up

quartz kindle
#

its bottom secret

sharp geyser
#

damn no embed

sharp geyser
wheat mesa
#

why not just use ts + private instead of #privateClassMemberThing

#

oh wait you're already using ts

#

why not private instead of the js version of "private"

sharp geyser
#

cause private doesn't actually make it private

wheat mesa
#

But neither does this

sharp geyser
#

according to voltrex it does

wheat mesa
#

object["#prop"]

#

always an option

#

private doesn't make anything private, it just hides it from the consumer of the API

quartz kindle
sharp geyser
#

Im just going based off what voltrex said ages ago when he was actually here

#

either way doesn't really matter to me

quartz kindle
#

the private keyword in ts will get compiled to either _ or # depending on your tsconfig

sharp geyser
#

right, so then whats the point of using private if im compiling down to it anyway

quartz kindle
#

whats the point of using private in general?

wheat mesa
#

so you don't have to do the #something shit

sharp geyser
wheat mesa
#

private is and has always been a concept of hiding things from other people

#

"encapsulation"

quartz kindle
#

which in js is useless and meaningless

sharp geyser
wheat mesa
#

it's just a message to others that "hey, this is internal implementation stuff you don't need to touch"

sharp geyser
#

yea

#

which is exactly why I use it

quartz kindle
sharp geyser
#

tim

#

you do stuff you probably shouldnt

#

😭

#

making the rest of us feel dumb

quartz kindle
#

if i dont, someone else will

sharp geyser
#

fair enough

#

but flexing on us normies

quartz kindle
#

lmao

#

im not flexing anything tho, just saying

#

js wasnt designed for this crap

wheat mesa
#

real chad move, inject into the memory of v8 instead of trying to mingle with js garbage

quartz kindle
#

i like js because everything is supposed to be hackable

#

when djs started doing the private crap, it was so anoying to deal with

wheat mesa
#

the primary users of djs are people that have 0 experience so it's understandable why they would want to hide stuff from them

quartz kindle
#

i much prefer the concept of underscore, like the concept of "not recommended to touch" instead of "fuck you cant touch this"

wheat mesa
#

that's valid

#

I'll just make a ts compiler with an "unprivate-ify" option

#

lol

sharp geyser
#

didnt know my code would spark such a debate

#

😭

quartz kindle
#

just make it compile to any js version pre-private

sharp geyser
#

Its so bad it made people debate about it

quartz kindle
#

yes

#

:^)

sharp geyser
#

Damn ok

pine willow
#

Lol

sharp geyser
#

@shell tundra sorry not making the framework anymore

#

tim crushed my spirits

quartz kindle
#

jk jk lmao

pine willow
quartz kindle
#

i need to decide on an http client to test my api with, people saying postman is old school now

sharp geyser
#

Honestly though what do you think about a plugin system in a djs framework tim

quartz kindle
#

although designing a plugin system is not easy

#

there are a shit ton of factors to consider

sharp geyser
#

Idk, it seems so out there. Like everything is run off plugins. So there's the core package that has the plugin loader, and the client class. Then you can make plugins like CommandHandler, EventHandler, etc and load them up

sharp geyser
#

you'd probably die and come back to life just to slap the fuck outta me

quartz kindle
#

its very hard to make a plugin system work in a sustainable way

#

either you lock it down to oblivion and allow only certified/tested plugins, to make sure they work and have quality

#

or you leave it open and people will dump a ton of garbage on it

sharp geyser
#

this is how i currently do it

quartz kindle
#

the problem with plugins for something like djs is

#

then you think plugin, you think plug and play, no code

#

with djs is like

#

why would i use a plugin when i can code this myself

sharp geyser
#

That's very fair

#

Technically its virtually no code other than the commands themselves. mmLol

#

The reason I went this approach though is a lot of frameworks add bloat ontop of djs which is already bloaty. Not to mention you typically wont use everything in a framework.

quartz kindle
#

if you wanna go fully into the idea of a plugin system, make an UI for it or something

#

some sort of automation

sharp geyser
#

So I thought plugins would be a better idea

#

Install what you need, leave out what you dont

#

It'd also allow people to make their own plugins

#

Since the plugin class is bundled in with the core package you don't really need to make a new package unless you want to share it to the world

quartz kindle
#

how about you enter an array of plugin names, and have the lib automatically download them and install them for you

#

on client load

sharp geyser
#

That could work yea.

quartz kindle
#

i'd avoid filling npm with plugins like npm i mylib/plugins/abc1 mylib/plugin/abc2, its so annoying lel

sharp geyser
#

If I do that I should probably port plugin class over to its own lib tho right?

quartz kindle
#

heres an idea to bring you above the competition

#

make your plugin class a lib for djs
when you install it it creates a local webserver that you can open in the browser
in the browser page you can browse/install/configure plugins

sharp geyser
#

This went from just making a framework for zobs, to me thinking lets help everyone

#

now you give me this golden idea

quartz kindle
#

lmao

sharp geyser
#

Honestly, why not just make my own lib at that point πŸ’€

quartz kindle
#

be careful tho, the mountain just got a lot bigger

sharp geyser
quartz kindle
#

like

#

person installs djs, then installs your lib

#

then runs yourlib with the djs client, or something

#

or just make your lib extend djs idk

#

you can make your lib already include djs, so the user doesnt need to install both

#

but the idea is basically turning into something no-code

#

like bdfd

#

lmao

sharp geyser
#

Well, that would be suitable for people who can't code.

#

But I dislike stuff like that 😭

#

Coding isn't about the easy way out

quartz kindle
#

indeed

sharp geyser
#

I'd rather not promote something like that

quartz kindle
#

thats why its hard to think about a plugin system

#

its hard to come up with something that will actually provide something interesting to other coders

sharp geyser
#

The original idea came from cargo's feature flags. So you get rid of what you don't need but keep what you do

#

so I was like, ight plugin system

#

It was meant to be for people looking for a framework that had a multitude of options. Like my official command handler plugin only supports slash commands.

#

Well if someone wanted a hybrid they'd be shit out of luck for the most part, cause typical frameworks bind the handlers to the client, not really letting you do much without ruining the system in place. So my idea of the plugin system was allow them to make their own handler to handle both message & slash commands if they wanted.

#

They could also publish these to npm to share with others.

quartz kindle
#

well good luck :^)

sharp geyser
#

😭

#

ty

#

I mean it works well for what it does I think

#

honestly just going to make an event handler, make some docs call it a day

#

if people make their own plugins neat!

quartz kindle
#

xD

mental glen
solemn latch
#

I really need to open source my embed visualization

sharp geyser
#

go for it

solemn latch
#

That's one thing I think I did a decent job on.
I'm sure a few people would appreciate a premade react component

sharp geyser
#

I'd so go for it

#

even if people don't like it, its something you put effort into.

#

Show it off

pearl trail
#

I'll like it

sharp geyser
#

Is it possible to simply check the value of a row in a postgres db? I simply want to see whether a row is true/false.

#

I don't need the data which is why im asking, as i'd rather just check the value if possible

pearl trail
sharp geyser
#

I figured it out

#

:p

pearl trail
#

:c

green kestrel
#

does anyone here speak dutch who might be able to help me with a really dumb issue? or anyone speak romanian?

#

(need some help fighting stupid censorship on both)

#

im trying to update application directory i18n pages

#

but i cant get my listing in dutch to work, or my listing in romanian

#

because the romanian word for 'how' reads as a swear in english as does the dutch word for 'can' (put them in gtranslate and see)

#

and discord, in their wisdom, apply english swear filters to all languages

#

so if anyone could suggest an alternate word in each case i could use... and i imagine this is kinda a silly question i should never have to ask.

#

if theres no way around it... i'll just have to put those localisations in english till the situation improves on discord's end...

sharp geyser
#

how come 😏

#

Ahem jokes aside, very interesting problem

#

hope it works out for ya

green kestrel
#

i might just have to tell everyone who finds my app directory page whos romanian or dutch that tough luck, discord says you gotta read english

sharp geyser
#

I'd just make it english for now tbh.

green kestrel
#

their swear filter is completely non contextual

sharp geyser
#

If you edit one word, it might mess up the entire translation.

green kestrel
#

so you could literally fill your english page with "zut alors, Discord c'est merde!"

sharp geyser
#

I know what tht means

#

(not really)

green kestrel
#

its french for 'discord is shit' basically

solemn latch
#

npm logs πŸ‘€

silly tarball no local data for webpack
#

okay silly tarball

lament rock
#

npm just being a little silly goober

surreal sage
#

LXC is basically a Docker container but with full access by the user
Basically a virtual machine but not, correct?

#

E.g. I want to run some project in an LXC, it would appear as a fresh install in a way?

#

my god .com nameserver propagation is crazy fast.

neon leaf
#

a vm has its own kernel

#

non-vm lxc shares with the host

surreal sage
#

perfeccctttt

frosty gale
#

im not entirely sure how dockers virtualisation works but i heard if you need to isolate potentially harmful or unpredictable environments then thats not a use for docker

lyric mountain
#

docker is more like the answer to "we cannot ship you machine to the client"

surreal sage
#

nah its just that i wanted to set up mediawiki

#

but it requires a ton of stuff to be installed

#

and i dont want to reinstall my system when i fuck up somehow

surreal sage
#

ncdu what

#

128 tb

#

fym

sharp geyser
#

@lyric mountain which join do I use again if I only want one side, but the other side is optional?

#

is it Left Join if I want A but B is fine to be null

#

or is that Right Join

lyric mountain
#

left yes

#

FROM smth LEFT JOIN smthelse

#

left where it's left from join

sharp geyser
#

Can I use this on a parent table query? Or do I have to do it on the child

lyric mountain
#

if you FROM the child table, you need to use RIGHT JOIN since you want all parents, children are optional

sharp geyser
lyric mountain
#

the standard is to always FROM the parent, then join the children

sharp geyser
#

okgotcha

#

time to write my first join statement

#

πŸ’€

#
SELECT x FROM parent p LEFT JOIN child c WHERE p.id = c.id AND email = $1
```?
lyric mountain
#

easy way to remember is that LEFT JOIN priorizes what comes before it, RIGHT JOIN priorizes what comes after

lyric mountain
sharp geyser
#

huh

lyric mountain
#

FROM parent p LEFT JOIN child c ON p.key = c.parent_key

sharp geyser
#

ah

lyric mountain
#

u need to tell which way to "connect" the tables

sharp geyser
#

so it just needs to be the column that has the fk referencing the other?

lyric mountain
#

yes

sharp geyser
#

error returned from database: column reference "student_id" is ambiguous

#

tf does this mean

#

πŸ’€

#

is it because both tables have the same column name

lyric mountain
#

alias

#

s.student_id

#

it's cuz both tables have a col with same name

sharp geyser
#

I am...?

lyric mountain
#

did u save the file?

#

oh

#

ur columns

#

SELECT ...

#

u need to state the alias here too

sharp geyser
#

like SELECT x,x,s.x?

lyric mountain
#

yes, for all columns

#

I mean, u dont need if there are no duplicates, but it's best to

sharp geyser
#

gotcha

#

hm

#

either I am doing something wrong, or the lib I am using to interact with pg is

lyric mountain
#

what error?

sharp geyser
#

no error

lyric mountain
#

what issue then?

sharp geyser
#

oh wait

#

if I want something from the other table

#

do I have to add that in the selection ?

lyric mountain
#

well, yes, u need to join them

#

and state in the select part

sharp geyser
#
let student = query!(
        "SELECT s.email, s.password, s.student_id FROM student s LEFT JOIN business b ON s.student_id = b.student_id WHERE email = $1",
        &login.email
    )

well...I am wanting something from the business table

lyric mountain
#

simply use b for accessing the values

sharp geyser
#

b.whatever after the SELECT?

lyric mountain
#

yes, like u do normally

#

you get what u state there

#

if u want all then just use *, but it's better to be specific

#

since rarely you'll need ALL the columns

sharp geyser
#

yea

#

tyty !

frosty gale
#

i never remember my joins

#

i always have to look them up

#

rarely do joins anyway because they're quite limited

#

you cant join something one to many for example because you need them to fit in the row

sharp geyser
#

most of my code theoretically works

#

have yet to fully test it so I have no idea if my joins work either

quartz kindle
#

code for months without testing anything

#

try to run the whole thing at once at the end

sharp geyser
#

I like the mystery

quartz kindle
#

thats basically what i do

#

xD

wheat mesa
sharp geyser
wheat mesa
#

Super helpful later on

sharp geyser
#

idek what those are or how to write em

wheat mesa
#

If you have a feature that you have very clearly defined behavior for, you should be writing unit tests for them

#

That way if something accidentally breaks, you’ll know immediately after you run your tests

sharp geyser
#

how do you write these unit tests

wheat mesa
sharp geyser
#

I can write these tests in the route files themselves right?

quartz kindle
#

unit testing is a nightmare

solemn latch
#

just trust AI to do it correctly.

#

ezpz

quartz kindle
#

integration testing is even worse

sharp geyser
#

unit testing would help me make sure stuff is getting run correctly, but for a api setting idfk how a unit test would look like

unreal umbra
#

I am trying to setup a status page what is the easy way to do it with bot hosting as it shows offline at the moment

sharp geyser
#

πŸ’€

wheat mesa
#

I mean I'm sure you have some sort of expected behavior/data returned

#

It's a bit more difficult when you have to integrate a database into it

#

That's where you get into patterns like Dependency Injection (Pretty common in C#/ASP)

sharp geyser
#

yea

#

I think ima continue testing with postman

#

ty for introducing me to tests tho

ionic schooner
#

whoever made the websites go-by-example and rust-by-example are the greatest humans ever.

sharp geyser
#

why are you learning go

ionic schooner
#

well I already know it but still. I was using it before I learned rust a few years ago

sharp geyser
#

im sorry for your loss

#

πŸ˜”

ionic schooner
#

lmaoo I agree, but now I'm a rust stan so its good

unreal umbra
#

I am trying to setup a status page on hetrixtools and it is not working when I try and ping the bot hosting and wanted to know if anyone has any easy way to make it ping the server when it is online.

frosty gale
wheat mesa
#

Too bad devon wasn’t real and it was a scam

quartz kindle
#

then you write tests for the endpointLogic function by importing it separately

sharp geyser
#

at that point why not just use postman instead of writing unit tests

wheat mesa
#

Because postman is manual

#

Unit testing can be automated

sharp geyser
#

meh

quartz kindle
#

because unit tests skip the http stack and test the logic directly

wheat mesa
#

That too

sharp geyser
#

I'd rather do it manually ngl

quartz kindle
#

the postman test is basically integration testing

#

unit test = test functions independently
integration test = test the whole system inputs and outputs

sharp geyser
#

Well thats what I want to do

wheat mesa
#

You can set up unit tests to automatically run on GitHub as well, that way if you have more people contributing you can guarantee that their behavior passes the tests automatically

quartz kindle
#

integration tests can also be automated, just write tests that run the server then call its own localhost endpoints

wheat mesa
#

Yeah but that’s a lot of work

#

Unit tests don’t require additional code in rust, you just… run them

sharp geyser
#

Ima just continue using postman πŸ‘ thanks for introducing me to unit testing tho

wheat mesa
#

(You have to write the tests, but there’s no fancy framework you need, it’s built in)

quartz kindle
sharp geyser
#

idk i've always had an account

quartz kindle
#

i switched to Bruno, still didnt play much with it, but gonna probably start using it more

sharp geyser
#

helps me sync my stuff

#

having an account is not a deal breaker for me

#

it allows me to sign in anywhere and have my endpoints ready to be tested

quartz kindle
#

its a minor annoyance for me

#

also Arc browser requires an account

#

ever heard of a brower that can only be used with an account?

spark flint
#

not as bad as edge

#

they send too many analytics logs

frosty gale
#

ive actually banned edge from my companys laptop hardening guide policy

#

way too many analytics indeed

#

too unsafe

quartz kindle
#

lmao

frosty gale
#

even if you turn eevrything off in settings they add more and stuff still gets sent

spark flint
spark flint
#

yes way

#

MITM proxy ftw

quartz kindle
#

"how many analytics frameworks do we wanna use?"
"yes"

ionic schooner
#

thats actually insane lmaooooooo

#

how much ram does that consume I wonder

quartz kindle
frosty gale
#

im looking into inspect and i dont get as many network requests

#

but they do literally track everything

#

i move my mouse and plenty requests get sent

spark flint
#

it nearly crashed my vm

sharp geyser
#

Medal on its way to leverage your hidden debts you didn't know about

quartz kindle
#

yeah, they track all of that pointer heatmap garbage and conversion funneling and all that marketing analytics bullshit

#

what has the internet become

sharp geyser
#

Well if we aren't making money off you viewing our site, we gotta make money off you visiting

#

:D

frosty gale
#

and sentry really tried to argue their case to get themselves removed from the analytics block list of major extensions

#

they argued that they only do error reporting and thats their main use purpose

#

why do 50 different sentry requests happen when i move my mouse on medal.tv then

#

unless an error is happening every mouse movement

quartz kindle
frosty gale
#

though in this case medal.tv is at fault and sentry is only really providing a service that they want

quartz kindle
#

plot twistΒ²: they throw errors on mouse move on purpose to trick sentry into being used for analytics

frosty gale
#

as expected the lighthouse score for performance on medal is abysmal

#

this can really quickly be narrowed down to using heavy frameworks and having a lot of bloat like analytics and etc

#

even on a website with tons of video playing at once you need to do a lot to get an awful lighthouse score

sharp geyser
#

whats youtube

#

I cba to check myself

#

or know how to check

frosty gale
#

exact same performance score as medal

#

they both share similarities

#

tons of analytics and heavy js files

ionic schooner
#

average big corpo moment tbh

spark flint
#

yes

sharp geyser
pearl trail
#

heya, let's say a module only says support up to .net framework 6.0 (there must be any right?), can i still use .net 8.0 with that module working? i'm new to c# so yeah PerliWorry

sharp geyser
#

I mean providing none of what it uses has been removed from .net 8 then possibly

pearl trail
#

ooo oke thanks!

past field
#

what is the best strategy for attaching image files to an embed?

sharp geyser
#

depends on the language and library you are using, though most of them are roughly the same

past field
#

i'm still on discord.js v13

#

slashcommandbuilder

sharp geyser
#

I dont even know how to find the docs for the v13

solemn latch
sharp geyser
#

Essentially you just make a new attachment, then attach that to your interaction.reply

#

or follow that

past field
dusky idol
#

Here to bother you again,
I was thinking if I could do "database catching" in my bot's code. I don't know what's the most efficient way to proceed with it tho, would need some advice.

Here's an example code

@commands.command()
async def wallet(self, ctx):
  data = await self.bot.economy.find_one()
  return await ctx.send(data)

Now instead of having this read request in my code and making my bot send one every time someone runs this command might be slower than just catching it up inside ram temprarity and reading it from there once the command is ran again.

I was hoping someone could tell me what's the best practice I can do to catchup data, I could store it in a global variable but i dunno if it's efficient or ideal.
Json files could also be a go-to but ehhhh
Has anyone done something similar to this before or got experience? It's MongoDB ofc

#

one straight forward idea I came up with is

catchedData = None
@commands.command()
async def wallet(self, ctx):
  if not catchedData:
    data = await self.bot.economy.find_one()
    catchedData = data
  else:
    data = catchedData
  return await ctx.send(data)

Even tho it's pretty simple and easy idk if it's the best option to store it in variable. Not to mention there'd be much-much complex commands in my bot doing more reads and writes

deft wolf
#

I think we had a conversation about this once and we came to the conclusion that probably all modern databases may have built-in caching

#
Does MongoDB handle caching?
Yes. MongoDB keeps most recently used data in RAM. If you have created indexes for your queries and your working data set fits in RAM, MongoDB serves all queries from memory.

MongoDB does not cache the query results in order to return the cached results for identical queries.

For more information on MongoDB and memory use, see WiredTiger and Memory Use.
tender river
#

Hello everyone

dusky idol
tulip ledge
# dusky idol Here to bother you again, I was thinking if I could do "`database catching`" in ...

Like NyNu said MongoDB handles caching for you. But if you still want to make your own cache you could use a tool like Redis or you could build your own by simple creating some form of hashmap with a specific timetolive per item (such that the cache gets cleared from the data if the data is no longer valid) you would then abstract this away by integrating it in your database query which you'd call by doing something like:

async def get(self, item): # Assume self is your database class (probably a MongoDB wrapper in your case)
  if item not in self.cache: # Check if the item is found in the cache
    data = await self.database.find_one() # If not query the data
    self.cache.insert(item, data) # Store the data in the cache 
    return data # Return the data
  return self.cache.get(item) # If it's found in the cache return the data
from threading import Timer

class Cache:
  def __init__(self):
    self._cache = {} # Initiate the cache
    self._lock = threading.lock() # Initiate the lock to ensure thread safety

  def insert(key, value, ttl=10):
    with self._lock: # Acquire the lock
      if key in self._cache: # Check if the key is already present
        self._cache[key]['timer'].cancel() # If so cancel the current timer

      timer = threading.Timer(ttl, self._remove, [key]) # Create a new timer
      self.cache[key] = {'value': value, 'timer': timer} # Insert the key with its value and ttl in the cache
      timer.start() # Start the timer

  def get(key):
    with self.lock: # Acquire the lock
      if key in self.cache: # Return the value if the key is present
        return self.cache[key]['value']
      return None

  def remove(key):
    with self.lock:  # Acquire the lock
    if key in self.cache: # Delete the value if the key is present
        del self.cache[key]

Then in your commands you'd just do self.database.get('key') and everything is nicely abstracted away for you

#

ofcourse this is a very simple cache and there's alot of optimizations you could do

#

it's also an example I just wrote like so and haven't tested so don't trust it that there are no flaws

dusky idol
# tulip ledge Like NyNu said MongoDB handles caching for you. But if you still want to make yo...

Ah yes thanks a lot for being detailed with it, I was just building a similar cache manager class, here's what i did

class CacheManager:
    def __init__(self, bot):
        self.bot = bot
        self.economy_cache = {}

    async def create_economy(self, user_id):
        await self.bot.db.economy.insert_one({
            "_id": user_id,
            "energy": 100,
            "fragmentcap": 100,
            "reset": 0,
            "vote": 0,
            "souls": 0,
            "souls_to_give": 0,
            "power": 0,
            "limit": 0

        })

    async def load_economy_cache(self):
        self.economy_cache = {}
        cursor = await self.bot.db.economy.find().to_list(length=None)
        for document in cursor:
            self.economy_cache[document["_id"]] = document

    async def get_economy_cache(self, user_id):
        return self.economy_cache.get(user_id)
    
    async def update_economy_cache(self, user_id, data):
        self.economy_cache[user_id] = data

    async def not_economy_cache(self, user_id):
        economyCatch = await self.get_economy_cache(user_id)
        if not economyCatch:
            economyCatch = await self.bot.db.economy.find_one({"_id": user_id})
            if not economyCatch:
                economyCatch = await self.create_economy(user_id=user_id)
            await self.update_economy_cache(user_id=user_id, data=economyCatch)
 
        return economyCatch
tulip ledge
#

so if your program has a long uptime you might run out of memory

dusky idol
#
    @commands.command(aliases=["bal", "balance", "coins"])
    async def wallet(self,ctx,member:disnake.Member=None):
        if self.prefix == "." and ctx.author.id != ZEKSY: return
        
        member = member or ctx.author
        economy = await self.bot.cache.get_economy_cache(member.id)

        if not economy: 
            print(f"I ran")
            economy = await self.bot.cache.not_economy_cache(member.id)

    
        coins = economy["energy"]
        resetTokens = economy["reset"]
        souls = economy["souls"]
        embed = disnake.Embed(title=f"{member.name}'s Wallet", color=disnake.Color.purple())
        embed.set_thumbnail(url=member.display_avatar.url)
        embed.description = f"""

![wallet](https://cdn.discordapp.com/emojis/1214139123242237974.webp?size=128 "wallet") **Wallet:**
{ARROW} Cursed Energy: **{coins}** {ENERGY}
{ARROW} Reset Tokens: **{resetTokens}** {RESET}
{ARROW} Souls: **{souls}** {SOUL}
"""
        await ctx.reply(embed=embed,allowed_mentions=disnake.AllowedMentions.none())

thats how im calling it for now

dusky idol
#

the whole cluster size is 80mbs, storing that much in ram should be fine

#

or does it increase for some reason?

tulip ledge
#

the whole point of a cache is to take advantage of temporal (and spacial) locality, where the idea is that when an item is queries it is likely to be queried again later on. Thus you want to only save it for a certain amount of time to clear up space

tulip ledge
#

if not. Why are you using a database if you only have 80mb of data that doesn't change?

dusky idol
tulip ledge
#

then why do you want a cache?

dusky idol
tulip ledge
#

essentially what you're doing now is storing everything in the database

#

then when a user uses the command you permanently save it to memory

#

and keep it there

#

so eventually all user's data will be in your memory

#

and there's no point in using a database anymore

sharp geyser
#

Ima be real...you are just caching already cached data.

dusky idol
# tulip ledge and there's no point in using a database anymore

I see your point now
The issue I'm facing with database is how slow it is with requests, maybe it's because I'm running it on free plan/regional factors.

Queries such as find_one adds delay to my commands and as some commands have a lot of queries, it increases the delay drastically especially when there are many users running the bot. Half of this is an assumption not point perfect information

Storing the database temprarily in RAM can help to speed up the reading aspect I think and bot only has to do writing to database making it faster performance wise.
Incase the bot shuts down and data is removed from ram it will still stay on the db's server.
Well that's pretty much the ideology

tulip ledge
dusky idol
#

instead of doing

await bot.db.econ.find_one```
i can just make the bot read it off memory thus making it slightly faster on paper
tulip ledge
#

If your database scales up to be pretty big you're essentially using memory which you don't need to use

#

for a discord bot you only have a couple commands right

dusky idol
tulip ledge
#

so a user only engages with the bot for lets say 5 minutes max

#

because of cooldowns I suppose

dusky idol
#

hm

tulip ledge
#

so after these 5 minutes their data is no longer needed to be in the cache

sharp geyser
#

Uhm Vigitillion, why are you spreading misinformation

tulip ledge
#

so you can clear it

sharp geyser
#

Well yes, databases are painfully slow because they have access to the file system which is painfully slow

#

Incorrect

tulip ledge
#

how come?

sharp geyser
#

Well, cloud databases as he is using rn aren't restricted based off file read/write speeds.

tulip ledge
dusky idol
sharp geyser
#

Even then, an sqlite database which is a file based db is very performant

tulip ledge
#

problem here is you have when requesting the data you first have to check if the data is still valid

#

which results in a slower get as apposed to a slower insert

#

and since you usally save the user to the database after the commands are finished I prefer a slower insert than a slower get since it reduces the time a user has to wait if you get what i mean

tulip ledge
sharp geyser
#

most sqlite clients cache in memory

tulip ledge
#

sure

#

but then you're still using a cache

#

thats my point

sharp geyser
#

right, one thats built in

tulip ledge
#

sure

sharp geyser
#

so adding one top is just more overhead

tulip ledge
#

I'm not saying it's the best solution to add one on top

#

I told them that mongo had one built in

#

and then told them how to do it if he wanted to build one on top

#

never told them it's the best approach

#

I still feel like building your own cache is a good excercise since you're getting more insight on how your data is handled by the database you're using

tulip ledge
sharp geyser
#

Fair enough, not saying don't do it. Just know that doing so for something that has cache already built in, makes little to no sense unless you are able to disable this caching layer and make your own.

dusky idol
tulip ledge
#

but once again, those are things you have to measure and choose the best approach based on the trade-offs and gains

sharp geyser
dusky idol
#

hm

sharp geyser
#

Even on the same machine its still restricted by whatever protocol it uses to connect to the database

#

will its latency be lower? most likely

dusky idol
#

how about read and write speed

sharp geyser
#

I'd say it'd be no more different than using atlas

tulip ledge
#

that's why I prefer databases without their own cache or one you can disable because i like to optimize everything so I just build my own cache each time

sharp geyser
#

but I also can't say for certain

tulip ledge
sharp geyser
#

The only time performance comes into question is when you have as many records as bun does

#

πŸ’€

#

@spark flint how many records is that again?

dusky idol
#

What I currently know is that the read and write speed is much slower when there's more traffic at certain times muidead

sharp geyser
#

few billion?

spark flint
#

1.2 billion

#

my aim is to have a record for everyone on earth

dusky idol
#

how do I check records

sharp geyser
#

How long does it take you to index those

spark flint
#

thats also only 2 months worth of data

spark flint
sharp geyser
#

πŸ’€

#

Poor you

spark flint
#

had to do it via a VM for it to stay online to index KEKW

tulip ledge
sharp geyser
dusky idol
tulip ledge
#

if it only has to read no

spark flint
tulip ledge
#

you can read concurrently

sharp geyser
tulip ledge
#

the problem is once you have a write, that can only happen on it's own

spark flint
#

ah

#

then yeah same KEKW

sharp geyser
#

imagine what happens when you actually do reach your 8 billion goal

dusky idol
sharp geyser
#

3 days -> 2 months

#

πŸ’€

tulip ledge
spark flint
#

only using 27% of my 1.5TB ssd atm

#

will upgrade when needed

tulip ledge
#

they'll get queued

#

and once the lock is free the next one can write

spark flint
#

it will also increase ram so I can optimise DB even more

sharp geyser
spark flint
#

yep!

dusky idol
sharp geyser
dusky idol
#

How do I prevent that

spark flint
#

no but a related project

sharp geyser
#

Ah

tulip ledge
#

it's more complicated really

sharp geyser
#

Actually yea makes sense you said a record for "every one"

tulip ledge
#

databases can handle a lot of traffic

dusky idol
tulip ledge
#

as long as your queries are well made but you're using nosql so it's fine I suppose

sharp geyser
spark flint
#

example doc entry: js { "id": "ZG9jcy50b3AuZ2ctMTcxMTQzNjEzMjg0NC1mZTY5NWI2Ny03ZGQ2LTRkMWYtYTc2OS1mMTYzMjNkZGM4ZDc", "domain": "docs.top.gg", "addresses": [ "top-gg.github.io", "185.199.108.153", "185.199.109.153", "185.199.110.153", "185.199.111.153" ], "rcode": "NOERROR", "hostname": "top.gg", "subdomain": "docs", "ns": [ "top-gg.github.io" ], "timestamp": "2024-03-26T06:55:32.845Z" },

#

probably

sharp geyser
tulip ledge
sharp geyser
#

Im in the rominik db

spark flint
tulip ledge
#

so if 100 users at once do it you're still ~0.1s

#

for the operations

dusky idol
sharp geyser
spark flint
#

yes

#

and other data

#

CC is in the db

sharp geyser
#

out here exposing me

dusky idol
#

well it could be because of free plan of atlas then? i mean the reason why im facing delay as that shit says "low network performance" specifically

spark flint
#

first seen 9th may, last seen 14th may

sharp geyser
#

lets not share this iara_nod

tulip ledge
# dusky idol i see

what modern databases do is use a write buffer, so instead of writing one at a time they store it into a big tray lets say and then write it all at once

spark flint
sharp geyser
#

ty

tulip ledge
#

that's why the traffic could increase a little for lots of writes since it waits for the writes to fill up this buffer

sharp geyser
#

I know its not "sensitive" information but ye

spark flint
#

i should check if any of my stuff is there

sharp geyser
tulip ledge
spark flint
#

also the speed of the query relates to how big the domain is

spark flint
#

nvm i had a c at the front

sharp geyser
tulip ledge
#

nosql databases are usually slower because you can't write your own queries and good queries can increase speeds by quite a bit

spark flint
#

yeah no logs

sharp geyser
#

Damn

dusky idol
sharp geyser
#

Ah wait you said 2 months ago

#

no wonder you have no record of it

tulip ledge
#

if you really want speed i'd suggest to leave mongo and use something like postgres

spark flint
sharp geyser
#

I bought and registered that domain with cloudflare like 1-2 years ago

spark flint
#

started late march

tulip ledge
spark flint
#

yeah that will be why

dusky idol
tulip ledge
#

that's a big issue

spark flint
#

its probabbly in one of my 2 old databases

sharp geyser
#

uh oh

dusky idol
sharp geyser
#

bro got reciptes (fuck cant spell rn)

spark flint
tulip ledge
tulip ledge
#

you were talkin about a .pay command?

dusky idol
tulip ledge
#

In my eyes it only requires 2 writes

#

and like I said, at the end of the command

dusky idol
#

why would a pay command have 10 writes xd

tulip ledge
#

after the user has gotten all their feedback

dusky idol
#

I should make it so it first gives the feedback and then does the writing

tulip ledge
#

yes

dusky idol
#

hm

tulip ledge
#

this way, if something goes wrong in the middle of your code you also haven't changed anything

#

this way you only write when everything went succesfull

dusky idol
#

right

tulip ledge
#

and the user doesn't get any delay from the writes

dusky idol
#

but like let's say for example

#

pay command has a write

tulip ledge
#

and then you can speed up the commands through a cache since you don't query the database anymore only the first time a user uses it's data

dusky idol
#
@commands.command()
async def pay(self, ctx):
  await ctx.send(f"you paid 100 coins")
  await self.bot.db.economy.update_one() 
tulip ledge
#

the problem you have with that approach however is if your app craches you lose data

dusky idol
tulip ledge
dusky idol
tulip ledge
#

they should get the correct value

dusky idol
tulip ledge
#

Discord latency to your bot is prob 60-70ms ping if your bot is hosted in the US

#

by then the write should have been completed

dusky idol
dusky idol
tulip ledge
dusky idol
tulip ledge
#

so closest to that

dusky idol
#

AH, I had buff ny as an option

tulip ledge
dusky idol
#

yeh someone said that it's us-east

tulip ledge
dusky idol
#

and unexpected crashes aren't under control

#

so its a no go pretty much

tulip ledge
tulip ledge
#

also, I'm not sure if it's in python but in javascript you can overwrite the behavior of a crash

#

so you could first make it store all the data in the cache to the database before it crashes

dusky idol
#

Also is there a way to somehow keep the bot online even when you push the changes muidead

#

I wouldn't assume that but like

tulip ledge
#

also, let's say you keep the user's data in the cache for 2 minutes and only write after the item "dies" which means the user hasn't made any changes to their state, in worst case scenario a user would only lose around 2 minutes of progress

dusky idol
#

Just incase

dusky idol
tulip ledge
#

yeah sure

#

that's the thing, to optimize you usally have to weigh in different aspects of certain solutions

dusky idol
tulip ledge
#

what if the read happens to read the same thing that gets written?

#

now you have no guarantee that the data is what you expected it to be

#

that's called a data race

tulip ledge
#

this way you essentially only use the blue environment and then push your updates and then build and whatever and once the environment is up and running you just switch and you got 0 downtime

lyric mountain
#

as long as u dont ctrl-c the process

tulip ledge
dusky idol
dusky idol
tulip ledge
tulip ledge
#

it's fun to implement such things

dusky idol
tulip ledge
#

and you learn a lot by doing it

tulip ledge
lyric mountain
#

also depending on what cache solution you use, there might be file-based persistence

#

like redis

dusky idol
#

I think I'm not using an unreliable one

lyric mountain
#

which can work off a file, meaning if it shutdowns out of the blue you still have the data onthe file

tulip ledge
#

already told them they could use redis aswell

lyric mountain
#

do note, however, you need to develop on linux if you plan to use redis

#

setting up redis on windows is...awful

solemn latch
#

I really need to use redis one of these days.
I've not really had a need for it yet

sharp geyser
#

brain pointed this out to me

#

kind of funny

solemn latch
#

Well that sucks πŸ‘€

dusky idol
# tulip ledge that's called a data race
@commands.command()
async def pay(self, ctx, amount):
  economy = await self.bot.cache.get_economy_cache(member.id) # getting data from cache

  if not economy: 
     print(f"I ran")
     economy = await self.bot.cache.not_economy_cache(member.id)
  
  if amount > economy["coins"]: return
  economy["coins"] -= amount

  await self.bot.cache.update_economy_cache(member.id, economy) # updating cached data of user
  await ctx.reply(f"Paid {amount} coins")
  await self.bot.db.economy.update_one() # doing write on db at end

This could possibly work, doing writing at the end, reading from cache and updating the cache itself everytime they run a command before sending result. This way the bot just shows output from cache and does writing on database as a side quest

lyric mountain
#

you need to await cache operations on d.py?

dusky idol
lyric mountain
#

oh nvm, that's your own methods

dusky idol
tulip ledge
lyric mountain
#

yeah, noticed it by the name

tulip ledge
#

wait no

dusky idol
tulip ledge
#
  economy = await self.bot.cache.get_economy_cache(member.id) # getting data from cache

  if not economy: 
     print(f"I ran")
     economy = await self.bot.cache.not_economy_cache(member.id)
#

you're getting from the cache

#

so yeah it shouldn't be await

#

or you implemented it wrong

#

but I feel like this could be abstracted away like I said

#

just have a method called .get() which gets from the cache and returns it if it exists and if not requests the database and stores it to the cache

dusky idol
tulip ledge
#

then instead have your write store the cache

lyric mountain
#

cache operations should be abstracted yeah

#

you should never need 2 calls to get an item

tulip ledge
#

and then when the item gets "killed" you store it to the db

dusky idol
#

hm

tulip ledge
#

so you abstract all the cache operations away

#

it's something the user shouldn't interact with

lyric mountain
#

nor the user neither you

dusky idol
#

What I see more of a challenge right now is to modify the cache within all commands

tulip ledge
#

well yeah I meant user of the api, being you

tulip ledge
#

this way you dont have to adjust all commands to then fix it and then adjust again

dusky idol
#

eitherway thanks for assisting and having a good talk, I'll work at that code now and see where I get with it

frosty gale
#

im connecting with contabo on LinkedIn somehow πŸ’€

tender river
#

Hala madrid βš™οΈ

carmine magnet
#

hello! is anyone familiar with mongoose with TypeScript? I am trying to use subdocuments in arrays but I am facing a type error.

My type definition of my schema is the following: ```ts
interface Series {
_id: ObjectId
id: number
names: Name[]
}
interface Name {
_id: ObjectId
lang: string
name: string
isAlternative?: boolean
isNative?: boolean
}
type THydratedNamedDocument = {
names: Types.DocumentArray<Name>
}
type GenericNamedModelType<T> = Model<T, {}, {}, {}, THydratedNamedDocument>

const seriesSchema = new Schema<Series, GenericNamedModelType<Series>>({
id: {
type: "Number",
required: true,
unique: true
},
names: [nameSchema]
})

const SeriesModel = model<Series, GenericNamedModelType<Series>>("series", seriesSchema)
When I am trying to use the `save` method on a series document, I am getting the error `Property 'save' doesn't exist in the type 'THydratedNamedDocument'` (example ts
const elt = await SeriesModel.findOne({ id: targetId })
const newname = elt.names.create(name)
elt.names.push(newname)
await elt.save()

lyric mountain
#

it's not about your schema, it's just that save() doesn't exist for elt

#

press ctrl space to see what methods are valid

#

whatever doesn't appear in autocomplete doesn't exist

carmine magnet
#

(I am importing Schema, model, Types, Model from mongoose)

carmine magnet
lyric mountain
#

apparently not on elt

carmine magnet
#

i'm just following the mongoose documentation

lyric mountain
#

btw, the error doesn't match the code you sent

#

Property 'save' doesn't exist but you didn't call a property, you called a method

#

it was supposed to say Function 'save()' doesn't exist

#

or smth like that

#

check if you saved the file

carmine magnet
#

idk, it's the error I have

lyric mountain
#

also show stacktrace, it should have one

carmine magnet
lyric mountain
#

hm

carmine magnet
#

that's in french so

lyric mountain
#

yeah I can guess the translation

carmine magnet
#

but propriΓ©tΓ© means property

lyric mountain
#

whatever you did doesn't include save in elt

carmine magnet
#

and ts2339 is indeed talking about property

lyric mountain
#

is it supposed to be a THydratedNamedDocument?

carmine magnet
#

it feels like the findOne does not return the right type

#

no it shouldn't be

lyric mountain
#

try casting the result to your document type

lyric mountain
sharp geyser
#

well yes it should be, because thats what you set the type as

#

you are overwriting the default type

#

so .save no longer exists

#

you should be extending the type if anything if you want to keep the original methods

carmine magnet
sharp geyser
#

erm

lyric mountain
#

type Name extends Another

#

I think

sharp geyser
#

nah

#

thats invalid syntax

lyric mountain
#

idk ts

sharp geyser
#

make it a interface

#
interface IHydratedNamedDocument extends Whatever {
  names: Types.DocumentArray<Name>
}
#

extend whatever the default return type of that is before you override it

carmine magnet
#

okay thank you

sharp geyser
#

or if you really want to use type still or are forced to

#

you can do type whatever = SomeAlreadyDefinedType & { names: Types.DocumentArray<Name> }

#

that's the way to extend a type in ts

lyric mountain
#

looks hacky af

sharp geyser
#

usually you'd set your type to something else

carmine magnet
#

yeah I am forced to because the type returned by findOne isn't an interface

sharp geyser
#
type YourType = { names: Types.DocumentArray<Name> }

type MergedTypes = SomeDefinedType & YourType
sharp geyser
#

welcome to ts

#

everything relating to the type system is hacky black magic

#

wait until you see some of the more complex types

lyric mountain
#

nah I'm fine

sharp geyser
#
type RecursiveType<T> = T extends object ? {
  [K in keyof T]: RecursiveType<T[K]>;
} : T;

#

dk what the fuck this is meant to do

#

I haven't used typescript in a while

#

? is a new one for me

carmine magnet
#

ternary operator

#

this one is easy to understand atleast

lyric mountain
#

funny how my new project despite being much more modular and heavily abusing inheritance is still more optimized than my old code

carmine magnet
#

because mongoose typings are so wierd

sharp geyser
#

Oh wait yea

#

fuck

lyric mountain
#

1st is new, 2nd is old

sharp geyser
#

so I was like wtf is that random ? doing

lyric mountain
#

eh, in fact java is built to be modular

carmine magnet
#

mongoose doc is so missleading

#

i've set my GenericNamedModelType to ```ts
type GenericNamedModelType<T> = Model<T, {}, {}, {}, Document<unknown, {}, T> & T & Required<{ _id: Types.ObjectId; }> & THydratedNamedDocument>

wheat mesa
lyric mountain
#

that's my bot

#

bottom row are the commands, the green line is the inheritance of the Executable interface

wheat mesa
#

Very structured

#

My game engine was lines fucking everywhere

lyric mountain
#

blue line is likely the Manager class (database acessor)

#

idk what the bold yellow line is

lyric mountain
eternal osprey
#

what color can i make the left button?

#

It's a buttn

real rose
#

for 2 buttons next to eachother

#

i usually do inverse

#

damn this message is 2h old

real rose
tulip ledge
#

I usually do the same

#

Also dutch speaking gang

real rose
#

ew

#

so many dutch people

sharp geyser
#

πŸ’€

proven lantern
#

why do all languages have "not equal" !=, but dont have not greater than/less than?

sharp geyser
#

huh

#

they do

#

> <

#

?

proven lantern
#

give me

#
    if (value != 1) {

    }

    if (value !> 1) {

    }```
sharp geyser
#

what language

#

js?

proven lantern
#

all c based basically

#

i think

sharp geyser
#

well

#

for one

#

you dont need to do !>

lyric mountain
#

That'd be just <= no?

proven lantern
#

you dont need != either

sharp geyser
#

yes you do

proven lantern
#
    if (value != 1) {

    }
    if (!(value == 1)) {

    }
sharp geyser
#

it makes no sense value is not greater than 1

#

well yea then it'd just be less than

#

value < 1

proven lantern
#

or equal

#

yea

sharp geyser
#

so !> or !< makes no sense

#

you'd just use the opposite sign

proven lantern
lyric mountain
#

Mf when if (value Β‘= 1)

#

"Might be equal to"

sharp geyser
proven lantern
sharp geyser
#

yea

#

i know

proven lantern
#

im making a preprocessor

lyric mountain
#

Why not also add <!> then?

#

"Not smaller nor greater"

sharp geyser
#

or !<!>! not not smaller nor not not greater

pearl trail
#

or !<=!==>! not less than or equal to not equal greater than or equal to not

sharp geyser
#

this should be its own language

#

oh wait...jsfuck

#

oh nvm jsfuck doesn't use <>=

#

it uses ()[]!+

lyric mountain
#

No parens, braces

sharp geyser
#

huh

lyric mountain
#

[]+{} is how you get [array Object]

#

Which is core for unlocking those letters

sharp geyser
#

😭

#

the fact you now this

lyric mountain
#

I did practice jsfuck a bit

sharp geyser
#

"practice"

#

who in their right mind

lyric mountain
#

[]+{}[![]+![]+![]+![]+![]] for example is y

proud rose
#

i need help with d.py, for my /ban i cant get it to return an error if the user isnt in the server

lyric mountain
#

The logic is pretty simple tbh

sharp geyser
#

πŸ’€

#

how the fuck does that equal y

lyric mountain
#

Easy to learn, but u can't read old code

lyric mountain
sharp geyser
#

is this in binary?

lyric mountain
#

Cuz js converts it to boolean

#

No, it's just js being funky

#

[] == 0

#

So ![] == true

sharp geyser
#

so 1+1+1+1+1

lyric mountain
#

Yes

sharp geyser
#

so 5

lyric mountain
#

It's technically true+true+true+...

sharp geyser
#

how does that equal y tho

lyric mountain
#

But js converts to number cuz u can't sum booleans

sharp geyser
#

is 5 like ascii or smth for y 😭

lyric mountain
#

[]+{} equals [array Object] for some stupid reason

#

[]+{}[...] is accessing the char at

#

So "[array Object]"[5]

#

Which is the sixth letter

#

So y

sharp geyser
#

im sorry

#

but uh

#

sixth letter of what

lyric mountain
#

Of the string

sharp geyser
#

what string

lyric mountain
#

There, added quotes

sharp geyser
#

well then by that logic its not y

#

oh wait

#

nvm

#

[ is a character

#

πŸ’€

lyric mountain
#

Yeah

sharp geyser
#

so is jsfuck valid js

#

just used in a weird way

lyric mountain
#

There are tricks to unlock the entire unicode dictionary

#

Some letters are really hard tho

sharp geyser
#

or is it its own esoteric language built on js

lyric mountain
#

Jsfuck is literally js

#

No custom rules, no custom compiler

#

Just raw js

sharp geyser
#

😭

lyric mountain
#

It works because js does some fcked up conversions

sharp geyser
#

you lie

lyric mountain
#

Hm, then I mightve missed something

#

Parens maybe?

sharp geyser
lyric mountain
#

But I don't remember jsfuck using parens

lyric mountain
#

Put [0] in front of it

#

Just to check

sharp geyser
#

jsfuck indeed uses parans btw

#

[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])

lyric mountain
#

Then that's it

sharp geyser
#

alert(1)

#

Also the kind of understanding you have to have of js

#

to come up with this

#

is insane

#

easy to teach

#

but imagine coming up with the idea of js fuck

#

πŸ’€

pearl trail
quartz kindle
#

the same type of idea as the movfuscator

sharp geyser
lyric mountain
#

Most of that code is getting eval() text

quartz kindle
#

basically a "what if" turned into a challenge

lyric mountain
#

Since u need it to run arbitrary code

quartz kindle
sharp geyser
# lyric mountain Since u need it to run arbitrary code

yea (![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]] is the actual alert(1)

sharp geyser
quartz kindle
#

its basically like if you were to create a whole program using only variable reassignment

#

without any other logic

sharp geyser
#

isnt that what most compilers do

quartz kindle
#

nop lul

sharp geyser
#

ic

quartz kindle
#

cpus have instructions, aka commands they can run

#

those instructions include math, comparisons, copy, move, etc

sharp geyser
#

asm is all about moving stuff in and out of registries and ram and such no?

lyric mountain
#

mov eax, ecx

#

Or smth

sharp geyser
#

that looks confusing

lyric mountain
#

That's assembly

sharp geyser
#

move eax to ecx?

quartz kindle
#

and some dude found a way to make any program run using only move instructions

sharp geyser
#

what eax and ecx are no idea

lyric mountain
#

It's been a long while since I had to use assembly

#

So I don't remember much

lyric mountain
#

But u have 4 registers

#

Eax, ebx, ecx and edx

#

There are some specific uses iirc to each

sharp geyser
#

ima be real

#

too tired to try and understand that

#

😭

quartz kindle
#

just pretend you do, clap and nod and pretend you're impressed

#

thats what i do :^)

lyric mountain
#

Jsfuck is fun to learn, but u need to highlight it somehow or idk, are comments allowed?