Shows how to get repo export and walk it in TypeScript walktherepo.wisp.place

a better timer

Changed files
+78 -7
src
+78 -7
src/lib/RepoStats.svelte
··· 21 21 let totalRecords = $state(0); 22 22 let startTime = $state<number | null>(null); 23 23 let endTime = $state<number | null>(null); 24 - let elapsedTime = $derived.by(() => { 24 + let elapsedTime = $state(''); 25 + 26 + let interval = $state<number | null>(null); 27 + 28 + const calculateElapsedTime = () => { 25 29 if (!startTime) return '0.00'; 26 30 const end = endTime ?? Date.now(); 27 - return ((end - startTime) / 1000).toFixed(2); 28 - }); 31 + elapsedTime = ((end - startTime) / 1000).toFixed(2); 32 + }; 33 + 34 + const startTimer = () => { 35 + interval = setInterval(() => { 36 + calculateElapsedTime(); 37 + }, 250); 38 + }; 29 39 30 40 const getRepoStats = async () => { 31 - const endPoint = `${pdsUrl}/xrpc/com.atproto.sync.getRepo?did=${did}`; 41 + const rpc = new Client({ handler: simpleFetchHandler({ service: pdsUrl }) }); 32 42 33 43 startTime = Date.now(); 34 44 endTime = null; 45 + startTimer(); 35 46 try { 36 - const response = await fetch(endPoint); 37 - if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); 47 + const result = await rpc.get('com.atproto.sync.getRepo', { 48 + params: { did: did }, 49 + as: 'stream', 50 + }); 38 51 39 - const car = fromStream(response.body); 52 + if (!result.ok ){ 53 + throw new Error(`HTTP error! status: ${result.status}`); 54 + } 55 + 56 + let stream = result.data; 57 + 58 + 59 + const car = fromStream(stream); 40 60 41 61 try { 42 62 for await (const entry of car) { ··· 55 75 totalRecords++; 56 76 } 57 77 }finally{ 78 + if (interval){ 79 + clearInterval(interval); 80 + interval = null; 81 + calculateElapsedTime(); 82 + } 58 83 await car.dispose(); 59 84 } 60 85 ··· 101 126 </ol> 102 127 {/if} 103 128 </div> 129 + 130 + <style> 131 + div::after { 132 + font: 800 40px system-ui; 133 + content: counter(count); 134 + animation: counter 5s linear infinite alternate; 135 + counter-reset: count 0; 136 + } 137 + 138 + @keyframes counter { 139 + 0% { 140 + counter-increment: count 0; 141 + } 142 + 10% { 143 + counter-increment: count 1; 144 + } 145 + 20% { 146 + counter-increment: count 2; 147 + } 148 + 30% { 149 + counter-increment: count 3; 150 + } 151 + 40% { 152 + counter-increment: count 4; 153 + } 154 + 50% { 155 + counter-increment: count 5; 156 + } 157 + 60% { 158 + counter-increment: count 6; 159 + } 160 + 70% { 161 + counter-increment: count 7; 162 + } 163 + 80% { 164 + counter-increment: count 8; 165 + } 166 + 90% { 167 + counter-increment: count 9; 168 + } 169 + 100% { 170 + counter-increment: count 10; 171 + } 172 + } 173 + 174 + </style>