thi-ng / umbrella

⛱ Broadly scoped ecosystem & mono-repository of 199 TypeScript projects (and ~180 examples) for general purpose, functional, data driven development
https://thi.ng
Apache License 2.0
3.35k stars 149 forks source link

[ksuid] allow for timestamp to be specified #372

Closed dmeehan1968 closed 1 year ago

dmeehan1968 commented 1 year ago

I have a use case where I'm receiving network data which has its own time source (milliseconds from unix epoch), but I want to preserve this timestamp (epoch) in the generated KSUID.

Delving into the source doesn't allow for a timestamp to be specified. next() might not be the right place for an optional epoch, so the following suggests a dedicated API.

It's possible to override the KSUID64 base class as follows:

class MyKSUID64 extends KSUID64 {
    fromEpoch(epoch: number = Date.now()) {
        const buf = this.timeOnlyBinary(epoch);
        return this.rnd
            ? randomBytesFrom(this.rnd, buf, this.epochSize)
            : randomBytes(buf, this.epochSize);
    }
}

This takes the base implementation of nextBinary() and allows the epoch to be specified and passed through. This overcomes an issue with using an instance of the base class from defKSUID64() as rnd is protected, so inheritance is required.

It would make sense to add this API higher in the inheritance chain, such as AKSUID.

Usage:

const id = new MyKSUID64()
id.fromEpoch(Date.now())    // or other millisecond count as long as its greater than or equal to the base epoch in options
postspectacular commented 1 year ago

Hi @dmeehan1968 - thank you for this, it's a really great idea and I can see it's usefulness! For consistency sake I've added both .fromEpoch() (formatted) and .fromEpochBinary() (bytes) methods and they're available for all 3 current implementations now...

v3.0.0 just released (there's an unrelated potentially breaking change in this version, hence the major version bump...)