+42
-25
src/views/blob/blob-export.tsx
+42
-25
src/views/blob/blob-export.tsx
···
1
1
import { FileSystemWritableFileStream, showSaveFilePicker } from 'native-file-system-adapter';
2
2
import { createSignal } from 'solid-js';
3
3
4
-
import { simpleFetchHandler, XRPC, XRPCError } from '@atcute/client';
4
+
import { Client, ClientResponseError, ok, simpleFetchHandler } from '@atcute/client';
5
5
import { type AtprotoDid, getPdsEndpoint, isAtprotoDid, isHandle } from '@atcute/identity';
6
6
import { writeTarEntry } from '@mary/tar';
7
7
···
65
65
service = endpoint;
66
66
}
67
67
68
-
const rpc = new XRPC({ handler: simpleFetchHandler({ service }) });
68
+
// const rpc = new XRPC({ handler: simpleFetchHandler({ service }) });
69
+
const client = new Client({ handler: simpleFetchHandler({ service }) });
69
70
70
71
// Grab a list of blobs
71
72
let blobs: string[] = [];
···
74
75
75
76
let cursor: string | undefined;
76
77
do {
77
-
const { data } = await rpc.get('com.atproto.sync.listBlobs', {
78
-
signal,
79
-
params: { did, cursor, limit: 1_000 },
80
-
});
78
+
const data = await ok(
79
+
client.get('com.atproto.sync.listBlobs', {
80
+
signal,
81
+
params: { did, cursor, limit: 1_000 },
82
+
}),
83
+
);
81
84
82
85
cursor = data.cursor;
83
86
blobs = blobs.concat(data.cids);
···
151
154
attempts++;
152
155
153
156
try {
154
-
const { data } = await rpc.get('com.atproto.sync.getBlob', {
157
+
const response = await client.get('com.atproto.sync.getBlob', {
155
158
signal,
159
+
as: 'bytes',
156
160
params: { did, cid },
157
161
});
158
162
159
-
return data;
160
-
} catch (err) {
161
-
if (attempts > 3) {
162
-
throw err;
163
+
if (response.ok) {
164
+
return response.data;
163
165
}
164
166
165
-
if (err instanceof XRPCError) {
166
-
if (err.status === 400) {
167
-
if (err.message === 'Blob not found') {
168
-
console.warn(`Blob ${cid} not found`);
169
-
return;
170
-
}
171
-
} else if (err.status === 429) {
172
-
const reset = err.headers?.['ratelimit-reset'];
167
+
if (response.status === 400) {
168
+
// If the PDS says it can't find the blob, stop right here.
169
+
if (response.data.message === 'Blob not found') {
170
+
logger.warn(`Blob ${cid} not found`);
171
+
return undefined;
172
+
}
173
+
} else if (response.status === 429) {
174
+
// Not exposed by CORS, hoping that someday it will
175
+
const reset = response.headers.get('ratelimit-reset');
173
176
174
-
if (reset !== undefined) {
175
-
logger.warn(`Ratelimit exceeded when downloading ${cid}, waiting`);
177
+
logger.warn(`Ratelimit exceeded when downloading ${cid}, waiting`);
176
178
177
-
const refreshAt = +reset * 1_000;
178
-
const delta = refreshAt - Date.now();
179
+
if (reset !== null) {
180
+
const refreshAt = +reset * 1_000;
181
+
const delta = refreshAt - Date.now();
179
182
180
-
await sleep(delta);
181
-
}
183
+
await sleep(delta);
184
+
} else {
185
+
await sleep(10_000);
182
186
}
183
187
}
188
+
189
+
if (attempts < 3) {
190
+
continue;
191
+
}
192
+
193
+
throw new ClientResponseError(response);
194
+
} catch (err) {
195
+
// Network errors, etc
196
+
if (attempts < 3) {
197
+
continue;
198
+
}
199
+
200
+
throw err;
184
201
}
185
202
}
186
203
};