handy online tools for AT Protocol boat.kelinci.net
atproto bluesky atcute typescript solidjs
20
fork

Configure Feed

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

refactor: use explicit resource management

Mary 472d3380 662ff70b

+69 -69
+22 -26
src/views/repository/car-unpack.tsx
··· 51 51 52 52 for (const { collection, rkey, record } of iterateAtpRepo(ui8)) { 53 53 if (writable === undefined) { 54 - const progress = logger.progress(`Waiting for the user`); 54 + using _progress = logger.progress(`Waiting for the user`); 55 55 56 - try { 57 - const fd = await showSaveFilePicker({ 58 - suggestedName: `${file.name.replace(/\.car$/, '')}.tar`, 56 + const fd = await showSaveFilePicker({ 57 + suggestedName: `${file.name.replace(/\.car$/, '')}.tar`, 59 58 60 - // @ts-expect-error: ponyfill doesn't have the full typings 61 - id: 'car-unpack', 62 - startIn: 'downloads', 63 - types: [ 64 - { 65 - description: 'Tarball archive', 66 - accept: { 'application/tar': ['.tar'] }, 67 - }, 68 - ], 69 - }).catch((err) => { 70 - console.warn(err); 59 + // @ts-expect-error: ponyfill doesn't have the full typings 60 + id: 'car-unpack', 61 + startIn: 'downloads', 62 + types: [ 63 + { 64 + description: 'Tarball archive', 65 + accept: { 'application/tar': ['.tar'] }, 66 + }, 67 + ], 68 + }).catch((err) => { 69 + console.warn(err); 71 70 72 - if (err instanceof DOMException && err.name === 'AbortError') { 73 - logger.warn(`Opened the file picker, but it was aborted`); 74 - } else { 75 - logger.warn(`Something went wrong when opening the file picker`); 76 - } 71 + if (err instanceof DOMException && err.name === 'AbortError') { 72 + logger.warn(`Opened the file picker, but it was aborted`); 73 + } else { 74 + logger.warn(`Something went wrong when opening the file picker`); 75 + } 77 76 78 - return undefined; 79 - }); 77 + return undefined; 78 + }); 80 79 81 - writable = await fd?.createWritable(); 82 - } finally { 83 - progress.destroy(); 84 - } 80 + writable = await fd?.createWritable(); 85 81 86 82 if (writable === undefined) { 87 83 // We already handled the errors above
+34 -41
src/views/repository/repo-export.tsx
··· 61 61 let fd: FileSystemFileHandle | undefined; 62 62 63 63 { 64 - const progress = logger.progress(`Waiting for the user`); 64 + using _progress = logger.progress(`Waiting for the user`); 65 65 66 - try { 67 - fd = await showSaveFilePicker({ 68 - suggestedName: `${identifier}-${new Date().toISOString()}.car`, 66 + fd = await showSaveFilePicker({ 67 + suggestedName: `${identifier}-${new Date().toISOString()}.car`, 69 68 70 - // @ts-expect-error: ponyfill doesn't have the full typings 71 - id: 'repo-export', 72 - startIn: 'downloads', 73 - types: [ 74 - { 75 - description: 'CAR archive file', 76 - accept: { 'application/vnd.ipld.car': ['.car'] }, 77 - }, 78 - ], 79 - }).catch((err) => { 80 - console.warn(err); 69 + // @ts-expect-error: ponyfill doesn't have the full typings 70 + id: 'repo-export', 71 + startIn: 'downloads', 72 + types: [ 73 + { 74 + description: 'CAR archive file', 75 + accept: { 'application/vnd.ipld.car': ['.car'] }, 76 + }, 77 + ], 78 + }).catch((err) => { 79 + console.warn(err); 81 80 82 - if (err instanceof DOMException && err.name === 'AbortError') { 83 - logger.warn(`Opened the file picker, but it was aborted`); 84 - } else { 85 - logger.warn(`Something went wrong when opening the file picker`); 86 - } 81 + if (err instanceof DOMException && err.name === 'AbortError') { 82 + logger.warn(`Opened the file picker, but it was aborted`); 83 + } else { 84 + logger.warn(`Something went wrong when opening the file picker`); 85 + } 87 86 88 - return undefined; 89 - }); 90 - } finally { 91 - progress.destroy(); 92 - } 87 + return undefined; 88 + }); 93 89 94 90 if (fd === undefined) { 95 91 // We already handled the errors above ··· 100 96 const writable = await fd.createWritable(); 101 97 102 98 { 103 - const progress = logger.progress(`Downloading CAR file`); 99 + using progress = logger.progress(`Downloading CAR file`); 100 + 101 + const repoUrl = new URL(`/xrpc/com.atproto.sync.getRepo?did=${did}`, service); 102 + const response = await fetch(repoUrl, { signal: signal }); 103 + 104 + if (!response.ok || !response.body) { 105 + logger.error(`Failed to retrieve CAR file`); 106 + return; 107 + } 104 108 105 109 let size = 0; 106 - try { 107 - const repoUrl = new URL(`/xrpc/com.atproto.sync.getRepo?did=${did}`, service); 108 - const response = await fetch(repoUrl, { signal: signal }); 109 110 110 - if (!response.ok || !response.body) { 111 - logger.error(`Failed to retrieve CAR file`); 112 - return; 113 - } 114 - 115 - for await (const chunk of iterateStream(response.body)) { 116 - size += chunk.length; 117 - writable.write(chunk); 111 + for await (const chunk of iterateStream(response.body)) { 112 + size += chunk.length; 113 + writable.write(chunk); 118 114 119 - progress.update(`Downloading CAR file (${formatBytes(size)})`); 120 - } 121 - } finally { 122 - progress.destroy(); 115 + progress.update(`Downloading CAR file (${formatBytes(size)})`); 123 116 } 124 117 125 118 logger.log(`CAR file downloaded (${formatBytes(size)})`);
+13 -2
vite.config.ts
··· 4 4 import solid from 'vite-plugin-solid'; 5 5 6 6 export default defineConfig({ 7 + esbuild: { 8 + target: 'es2023', 9 + }, 7 10 build: { 8 - target: 'esnext', 11 + target: 'es2023', 9 12 modulePreload: false, 10 13 sourcemap: true, 11 14 assetsInlineLimit: 0, ··· 45 48 '~': path.join(__dirname, './src'), 46 49 }, 47 50 }, 48 - plugins: [solid()], 51 + plugins: [ 52 + solid({ 53 + babel: { 54 + parserOpts: { 55 + plugins: ['explicitResourceManagement'], 56 + }, 57 + }, 58 + }), 59 + ], 49 60 });