this repo has no description

feat: add TID generation for record keys

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Changed files
+68 -2
src
test
+38 -1
src/pds.js
··· 105 105 return result 106 106 } 107 107 108 + // === TID GENERATION === 109 + // Timestamp-based IDs: base32-sort encoded microseconds + clock ID 110 + 111 + const TID_CHARS = '234567abcdefghijklmnopqrstuvwxyz' 112 + let lastTimestamp = 0 113 + let clockId = Math.floor(Math.random() * 1024) 114 + 115 + function createTid() { 116 + let timestamp = Date.now() * 1000 // microseconds 117 + 118 + // Ensure monotonic 119 + if (timestamp <= lastTimestamp) { 120 + timestamp = lastTimestamp + 1 121 + } 122 + lastTimestamp = timestamp 123 + 124 + // 13 chars: 11 for timestamp (64 bits but only ~53 used), 2 for clock ID 125 + let tid = '' 126 + 127 + // Encode timestamp (high bits first for sortability) 128 + let ts = timestamp 129 + for (let i = 0; i < 11; i++) { 130 + tid = TID_CHARS[ts & 31] + tid 131 + ts = Math.floor(ts / 32) 132 + } 133 + 134 + // Append clock ID (2 chars) 135 + tid += TID_CHARS[(clockId >> 5) & 31] 136 + tid += TID_CHARS[clockId & 31] 137 + 138 + return tid 139 + } 140 + 108 141 export class PersonalDataServer { 109 142 constructor(state, env) { 110 143 this.state = state ··· 124 157 const cid = await createCid(data) 125 158 return Response.json({ cid: cidToString(cid) }) 126 159 } 160 + if (url.pathname === '/test/tid') { 161 + const tids = [createTid(), createTid(), createTid()] 162 + return Response.json({ tids }) 163 + } 127 164 return new Response('pds running', { status: 200 }) 128 165 } 129 166 } ··· 144 181 } 145 182 146 183 // Export utilities for testing 147 - export { cborEncode, createCid, cidToString, base32Encode } 184 + export { cborEncode, createCid, cidToString, base32Encode, createTid }
+30 -1
test/pds.test.js
··· 1 1 import { test, describe } from 'node:test' 2 2 import assert from 'node:assert' 3 - import { cborEncode, createCid, cidToString, base32Encode } from '../src/pds.js' 3 + import { cborEncode, createCid, cidToString, base32Encode, createTid } from '../src/pds.js' 4 4 5 5 describe('CBOR Encoding', () => { 6 6 test('encodes simple map', () => { ··· 113 113 assert.notStrictEqual(cid1, cid2) 114 114 }) 115 115 }) 116 + 117 + describe('TID Generation', () => { 118 + test('creates 13-character TIDs', () => { 119 + const tid = createTid() 120 + assert.strictEqual(tid.length, 13) 121 + }) 122 + 123 + test('uses valid base32-sort characters', () => { 124 + const tid = createTid() 125 + assert.match(tid, /^[234567abcdefghijklmnopqrstuvwxyz]+$/) 126 + }) 127 + 128 + test('generates monotonically increasing TIDs', () => { 129 + const tid1 = createTid() 130 + const tid2 = createTid() 131 + const tid3 = createTid() 132 + 133 + assert.ok(tid1 < tid2, `${tid1} should be less than ${tid2}`) 134 + assert.ok(tid2 < tid3, `${tid2} should be less than ${tid3}`) 135 + }) 136 + 137 + test('generates unique TIDs', () => { 138 + const tids = new Set() 139 + for (let i = 0; i < 100; i++) { 140 + tids.add(createTid()) 141 + } 142 + assert.strictEqual(tids.size, 100) 143 + }) 144 + })