kra8 / laravel-snowflake

This Laravel package to generate 64 bit identifier like the snowflake within Twitter.
MIT License
154 stars 18 forks source link

Compatibility with Javascript #22

Closed ghost closed 2 years ago

ghost commented 4 years ago

Hey great package!

Is it possible to configure the generator to create only 16 or 15 digit numbers?

I'm pushing my Eloquent collections to Vue components and Javascript's Number.MAX_SAFE_INTEGER is only 16 digits, thus all the IDs are getting rounded and no longer match the actual db ID.

Thanks

kra8 commented 4 years ago

I use it a lot with JavaScript too.

In that case, I cast it as a string as below:

class Sample extends Model
{
    use HasSnowflakePrimary;

    protected $casts = [
        'id' => 'string',
    ];
}

Or do you want to treat your ID as a number in JavaScript?

ghost commented 4 years ago

Yes this is what I did in the interim, but honestly I would prefer to use them as numbers.

For my needs I'm pretty sure that 15 digits would be more than plenty, but looking at your code I didn't see how to overload the method and make them just a tad shorter.

Thanks for the help and once again for the excellent package.

kra8 commented 4 years ago

Okay. Indeed, it makes sense for Snowflake to be a number. I will think the options so that they fit within the number of digits in JavaScript.

Thank you.

ghost commented 4 years ago

Great thanks.

Let me know if there's anything I can do to help.

kra8 commented 4 years ago

Hi, i thought a little.

Snowflake is build from 64-bit integers. However, JavaScript only supports up to 53-bit integers.

So, you have to reduce the information you include in snowflake ID. We don't want to reduce the number of digits used for timestamp, so the number of nodes in a distributed data center or worker will be very small.

ghost commented 4 years ago

Ok.

So how do we make the change to get this to produce 53 bit integers?

pqt commented 3 years ago

Hey @19peaches just incase you aren't aware you can use this in JS with a little bit of legwork in converting it to a BigInt. https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/bigint

const alsoHuge = BigInt(9007199254740991)
// ↪ 9007199254740991n

This would let you return stuff like API responses as proper number values but also work with the JavaScript side (with zero changes/overrides to this package too!)

ghost commented 3 years ago

@pqt

I would prefer to not have to wrangle with values in Javascript, these are database ids and being used much too often to have to be transposed to something else.

A change to the config somewhere to get smaller javascript safe numbers is the correct choice.

Thanks for the info.

kra8 commented 2 years ago

Add HasShortPrimary Trait. from v2.1.0

seabasss commented 2 years ago

Thanks for this!

Apart from different lengths, does anyone have any intel on the difference in performance and usage between HasSnowflakePrimary and HasShortPrimary?

E.g. the shorter ID's can handle x number of records with x amount of data centers, while the longer can do y and z? I like the shorter ID's in terms of dealing with JS, but also don't want to paint myself in a corner in a few years and not be able to expand, although we're probably talking about billions of records before that becomes an issue.

Thanks!