a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(tid): faster encode/decode

Mary a46b7efd a891529d

+39 -9
+1 -1
.changeset/bright-snails-hide.md
··· 2 2 '@atcute/cbor': patch 3 3 --- 4 4 5 - quickly bail out to slow path on server runtimes 5 + quickly bail out to slow path on server runtimes
+5
.changeset/little-bars-care.md
··· 1 + --- 2 + '@atcute/tid': patch 3 + --- 4 + 5 + faster encode/decode
+5 -5
packages/utilities/tid/lib/index.ts
··· 2 2 3 3 import { random } from '#platform/random'; 4 4 5 - import { s32decode, s32encode } from './s32.ts'; 5 + import { S32_2CHAR_TABLE, s32decode, s32encode } from './s32.ts'; 6 6 7 7 let lastTimestamp = 0; 8 8 let lastCurrentTime = 0; ··· 13 13 * Creates a TID based off provided timestamp and clockid, with no validation. 14 14 */ 15 15 export const createRaw = (timestamp: number, clockid: number): string => { 16 - return s32encode(timestamp).padStart(11, '2') + s32encode(clockid).padStart(2, '2'); 16 + return s32encode(timestamp).padStart(11, '2') + S32_2CHAR_TABLE[clockid]!; 17 17 }; 18 18 19 19 /** ··· 59 59 throw new Error(`invalid TID`); 60 60 } 61 61 62 - const timestamp = s32decode(tid.slice(0, 11)); 63 - const clockid = s32decode(tid.slice(11, 13)); 62 + const timestamp = s32decode(tid, 0, 11); 63 + const clockid = s32decode(tid, 11, 2); 64 64 65 - return { timestamp: timestamp, clockid: clockid }; 65 + return { timestamp, clockid }; 66 66 }; 67 67 68 68 /**
+28 -3
packages/utilities/tid/lib/s32.ts
··· 1 1 const S32_CHAR = '234567abcdefghijklmnopqrstuvwxyz'; 2 2 3 + const S32_DECODE_TABLE = (() => { 4 + const table = new Int16Array(123); 5 + table.fill(-1); 6 + 7 + for (let i = 0; i < S32_CHAR.length; i++) { 8 + const code = S32_CHAR.charCodeAt(i); 9 + table[code] = i; 10 + } 11 + 12 + return table; 13 + })(); 14 + 15 + export const S32_2CHAR_TABLE = (() => { 16 + const table = Array.from<string>({ length: 1024 }); 17 + 18 + for (let i = 0; i < 1024; i++) { 19 + const hi = S32_CHAR.charAt((i >> 5) & 31); 20 + const lo = S32_CHAR.charAt(i & 31); 21 + table[i] = hi + lo; 22 + } 23 + 24 + return table; 25 + })(); 26 + 3 27 export const s32encode = (i: number): string => { 4 28 let s = ''; 5 29 ··· 12 36 return s; 13 37 }; 14 38 15 - export const s32decode = (s: string): number => { 39 + export const s32decode = (s: string, offset: number, length: number): number => { 16 40 let i = 0; 41 + const end = offset + length; 17 42 18 - for (const c of s) { 19 - i = i * 32 + S32_CHAR.indexOf(c); 43 + for (let idx = offset; idx < end; idx++) { 44 + i = i * 32 + S32_DECODE_TABLE[s.charCodeAt(idx)]!; 20 45 } 21 46 22 47 return i;