Because there is no NanoId to Uint8Array conversion, I spent two hours making it (one hour of googling any existing code, nothing exists). Maybe it can help someone. I did it for https://github.com/evoluhq/evolu
const nanoIdAlphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
export const encodeId = (id: Id): WrappedBuffer => {
/**
* NanoId has 21 chars, but we can compress it to 16 bytes because of the
* limited alphabet.
*/
const value = new Uint8Array(16);
let bitBuffer = 0;
let bitsInBuffer = 0;
let byteIndex = 0;
for (let i = 0; i < 21; i++) {
const charValue = nanoIdAlphabet.indexOf(id[i]);
bitBuffer = (bitBuffer << 6) | charValue;
bitsInBuffer += 6;
while (bitsInBuffer >= 8) {
bitsInBuffer -= 8;
value[byteIndex++] = (bitBuffer >> bitsInBuffer) & 0xff;
}
}
if (bitsInBuffer > 0) {
value[byteIndex] = (bitBuffer << (8 - bitsInBuffer)) & 0xff;
}
return new WrappedBuffer(value);
};
export const decodeId = (
buffer: WrappedBuffer,
): Effect.Effect<Id, BinaryParseEndsPrematurelyError> =>
pipe(
buffer.shiftN(16 as NonNegativeInt),
Effect.map((value) => {
let bitBuffer = 0;
let bitsInBuffer = 0;
let id = "";
for (let i = 0; i < 16; i++) {
bitBuffer = (bitBuffer << 8) | value[i];
bitsInBuffer += 8;
while (bitsInBuffer >= 6) {
bitsInBuffer -= 6;
const charValue = (bitBuffer >> bitsInBuffer) & 0x3f;
id += nanoIdAlphabet[charValue];
}
}
return id as Id;
}),
);
Because there is no NanoId to Uint8Array conversion, I spent two hours making it (one hour of googling any existing code, nothing exists). Maybe it can help someone. I did it for https://github.com/evoluhq/evolu