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

daisyui

Changed files
+136 -58
src
+19 -20
src/App.svelte
··· 18 18 19 19 </script> 20 20 21 - <main> 22 - {#if showRepoStats} 23 - {#if slowPoke} 24 - <h2>Walking the repo via api calls</h2> 25 - {:else} 26 - <h2>Walking the repo via repo export</h2> 27 - {/if} 28 - {:else} 29 - <h1>Repo Walk Example</h1> 30 - <br> 31 - <p>Demo showing why you may rather export the users whole repo instead of walking it via api calls</p> 32 - <sub>Also shows how many records you have and how many of each kind if you're into that kind of thing...</sub> 33 - {/if} 34 - <div class="card"> 21 + <main class="container mx-auto px-4 py-8 max-w-4xl"> 22 + <div class="text-center mb-8"> 35 23 {#if showRepoStats} 36 - <RepoStats did={did} pdsUrl={pdsUrl} slowPokeMode={slowPoke}/> 24 + {#if slowPoke} 25 + <h2 class="text-3xl font-bold text-primary">Walking the repo via api calls</h2> 26 + {:else} 27 + <h2 class="text-3xl font-bold text-primary">Walking the repo via repo export</h2> 28 + {/if} 37 29 {:else} 38 - <SearchForm resolvedResult={resolvedResult}/> 30 + <h1 class="text-5xl font-bold mb-4">Repo Walk Example</h1> 31 + <p class="text-lg mb-2">Demo showing why you may rather export the users whole repo instead of walking it via api calls</p> 32 + <p class="text-sm opacity-70">Also shows how many records you have and how many of each kind if you're into that kind of thing...</p> 39 33 {/if} 40 34 </div> 41 35 36 + <div class="card bg-base-200 shadow-xl"> 37 + <div class="card-body"> 38 + {#if showRepoStats} 39 + <RepoStats did={did} pdsUrl={pdsUrl} slowPokeMode={slowPoke}/> 40 + {:else} 41 + <SearchForm resolvedResult={resolvedResult}/> 42 + {/if} 43 + </div> 44 + </div> 42 45 </main> 43 - 44 - <style> 45 - 46 - </style>
+85 -28
src/lib/RepoStats.svelte
··· 185 185 186 186 </script> 187 187 188 - <div> 189 - {#if slowPokeMode} 190 - <img alt="A Shellder biting a Slowpoke's tail, as seen in the Pokémon anime " 191 - src="/slowPoke.png"> 192 - <br> 188 + <div class="flex flex-col items-center gap-4"> 189 + <div class="w-full flex justify-center"> 190 + {#if slowPokeMode} 191 + <img 192 + alt="A Shellder biting a Slowpoke's tail, as seen in the Pokémon anime" 193 + src="/slowPoke.png" 194 + class="max-w-sm rounded-lg shadow-lg" 195 + > 193 196 {:else} 194 - <img alt="text in a speech bubble that says 'Dude, wheres my car'" src="/dude.png"> 195 - <br> 196 - {/if} 197 + <img 198 + alt="text in a speech bubble that says 'Dude, wheres my car'" 199 + src="/dude.png" 200 + class="max-w-sm rounded-lg shadow-lg" 201 + > 202 + {/if} 203 + </div> 197 204 198 205 {#if error} 199 - <p style="color: red">{error}</p> 206 + <div class="alert alert-error w-full"> 207 + <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"> 208 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /> 209 + </svg> 210 + <span>{error}</span> 211 + </div> 200 212 {/if} 213 + 201 214 {#if loading && !slowPokeMode} 202 - Loading... ({downloadedMB} MB downloaded, {elapsedTime}s) 215 + <div class="flex items-center gap-3"> 216 + <span class="loading loading-spinner loading-lg text-primary"></span> 217 + <div class="text-lg"> 218 + <div class="font-semibold">Loading...</div> 219 + <div class="text-sm opacity-70"> 220 + <span class="badge badge-info">{downloadedMB} MB</span> downloaded in 221 + <span class="badge badge-ghost">{elapsedTime}s</span> 222 + </div> 223 + </div> 224 + </div> 203 225 {:else if loading && slowPokeMode} 204 - Loading... ({webCalls.toLocaleString()} web calls made, {elapsedTime}s) 226 + <div class="flex items-center gap-3"> 227 + <span class="loading loading-spinner loading-lg text-primary"></span> 228 + <div class="text-lg"> 229 + <div class="font-semibold">Loading...</div> 230 + <div class="text-sm opacity-70"> 231 + <span class="badge badge-info">{webCalls.toLocaleString()} web calls</span> made in 232 + <span class="badge badge-ghost">{elapsedTime}s</span> 233 + </div> 234 + </div> 235 + </div> 205 236 {:else} 206 - {#if !slowPokeMode} 207 - <span>Repo size {downloadedMB} MB (fetched in {elapsedTime}s)</span> 208 - {:else} 209 - <span>Web calls made: {webCalls.toLocaleString()} (fetched in {elapsedTime}s)</span> 210 - {/if} 237 + <div class="stats shadow bg-base-300"> 238 + <div class="stat"> 239 + <div class="stat-title">{slowPokeMode ? 'Web Calls Made' : 'Repo Size'}</div> 240 + <div class="stat-value text-primary"> 241 + {#if !slowPokeMode} 242 + {downloadedMB} MB 243 + {:else} 244 + {webCalls.toLocaleString()} 245 + {/if} 246 + </div> 247 + <div class="stat-desc">Fetched in {elapsedTime}s</div> 248 + </div> 249 + </div> 211 250 {/if} 251 + 212 252 {#if loading && currentCollection !== null} 213 - <br> 214 - <span>Currently walking collection: {currentCollection}</span> 253 + <div class="alert alert-info"> 254 + <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6"> 255 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path> 256 + </svg> 257 + <span>Currently walking collection: <strong>{currentCollection}</strong></span> 258 + </div> 215 259 {/if} 216 260 217 261 {#if collectionsOrdered.length > 0} 262 + <div class="stats stats-vertical lg:stats-horizontal shadow bg-base-300 w-full"> 263 + <div class="stat"> 264 + <div class="stat-title">Total Records</div> 265 + <div class="stat-value text-secondary">{totalRecords.toLocaleString()}</div> 266 + </div> 267 + <div class="stat"> 268 + <div class="stat-title">Different Collections</div> 269 + <div class="stat-value text-accent">{collectionsOrdered.length}</div> 270 + </div> 271 + </div> 218 272 219 - <br> 220 - <span>Total Records: {totalRecords.toLocaleString()}</span> 221 - <br> 222 - <span>Different Collections: {collectionsOrdered.length}</span> 223 - <br> 224 - <ol style="text-align: left;"> 225 - {#each collectionsOrdered as collection (collection.collection)} 226 - <li>{collection.collection} ({collection.count.toLocaleString()} records)</li> 227 - {/each} 228 - </ol> 273 + <div class="card bg-base-300 shadow-xl w-full"> 274 + <div class="card-body"> 275 + <h3 class="card-title">Collections Breakdown</h3> 276 + <ol class="list-decimal list-inside space-y-2"> 277 + {#each collectionsOrdered as collection (collection.collection)} 278 + <li class="text-sm"> 279 + <span class="font-mono text-primary">{collection.collection}</span> 280 + <span class="badge badge-sm ml-2">{collection.count.toLocaleString()} records</span> 281 + </li> 282 + {/each} 283 + </ol> 284 + </div> 285 + </div> 229 286 {/if} 230 287 </div>
+32 -10
src/lib/SearchForm.svelte
··· 58 58 59 59 </script> 60 60 61 - <form onsubmit={searchForUser}> 62 - <label for="search">ATProto Handle</label> 63 - <input bind:value={handleToLookUp} id="search" type="text" placeholder="alice.bsky.social"/> 64 - <button>walk by {slowpoke ? 'api calls' : 'repo export'}</button> 65 - <br> 66 - <label> 67 - <input bind:checked={slowpoke} type="checkbox"/> 68 - slowpoke (uses web calls to walk the repository to show you the speed difference) 61 + <form onsubmit={searchForUser} class="space-y-4"> 62 + <div class="form-control w-full"> 63 + <label class="label" for="search"> 64 + <span class="label-text font-semibold">ATProto Handle</span> 65 + </label> 66 + <input 67 + bind:value={handleToLookUp} 68 + id="search" 69 + type="text" 70 + placeholder="alice.bsky.social" 71 + class="input input-bordered w-full" 72 + /> 73 + </div> 69 74 70 - </label> 75 + <div class="form-control"> 76 + <label class="label cursor-pointer justify-start gap-3"> 77 + <input bind:checked={slowpoke} type="checkbox" class="checkbox checkbox-primary"/> 78 + <span class="label-text">slowpoke (uses web calls to walk the repository to show you the speed difference)</span> 79 + </label> 80 + </div> 81 + 71 82 {#if error} 72 - <p style="color: red;">Error: {error}</p> 83 + <div class="alert alert-error"> 84 + <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"> 85 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /> 86 + </svg> 87 + <span>Error: {error}</span> 88 + </div> 73 89 {/if} 90 + 91 + <div class="form-control mt-6"> 92 + <button class="btn btn-primary"> 93 + Walk by {slowpoke ? 'API Calls' : 'Repo Export'} 94 + </button> 95 + </div> 74 96 </form>