Skip to content

Commit 1f5cc10

Browse files
committed
feat: Improve data source robustness by probing multiple recent files and add clipboard copy fallback for wider compatibility.
1 parent 53fce24 commit 1f5cc10

2 files changed

Lines changed: 34 additions & 13 deletions

File tree

‎src/App.tsx‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,23 @@ function ErrorScreen() {
9696

9797
const handleCopy = () => {
9898
const text = `Error: ${error?.message}\n\n${errorDetail || 'No logs'}`;
99-
navigator.clipboard.writeText(text).then(() => {
99+
// navigator.clipboard fails on iOS WebKit without secure context;
100+
// fall back to textarea + execCommand
101+
const copy = () => {
102+
if (navigator.clipboard?.writeText) {
103+
return navigator.clipboard.writeText(text);
104+
}
105+
const ta = document.createElement('textarea');
106+
ta.value = text;
107+
ta.style.position = 'fixed';
108+
ta.style.opacity = '0';
109+
document.body.appendChild(ta);
110+
ta.select();
111+
document.execCommand('copy');
112+
document.body.removeChild(ta);
113+
return Promise.resolve();
114+
};
115+
copy().then(() => {
100116
setCopied(true);
101117
setTimeout(() => setCopied(false), 2000);
102118
});

‎src/lib/duckdb-client.ts‎

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,13 @@ export async function configureHttpFS(): Promise<void> {
122122
*/
123123
function generateFallbackFileList(): ParquetFileInfo[] {
124124
const START = new Date(2026, 0, 1); // Jan 1 2026 — earliest data
125-
const today = new Date();
125+
// Stop at yesterday — today's file may not be uploaded yet
126+
const yesterday = new Date();
127+
yesterday.setDate(yesterday.getDate() - 1);
126128
const files: ParquetFileInfo[] = [];
127129
const cur = new Date(START);
128130

129-
while (cur <= today) {
131+
while (cur <= yesterday) {
130132
const y = cur.getFullYear();
131133
const m = String(cur.getMonth() + 1).padStart(2, '0');
132134
const d = String(cur.getDate()).padStart(2, '0');
@@ -183,19 +185,22 @@ export async function discoverParquetFiles(): Promise<ParquetFileInfo[]> {
183185

184186
/**
185187
* Test if a data source works by running a lightweight probe query.
188+
* Tries the last few files in case the very latest doesn't exist yet.
186189
*/
187190
export async function testDataSource(root: DataRoot, files: ParquetFileInfo[]): Promise<boolean> {
188-
try {
189-
// Always probe with a single file — avoids glob scanning all files
190-
const sampleFile = files[files.length - 1]!;
191-
const url = `${DATA_ROOTS[root]}${PATH_PREFIX}${sampleFile.filename}`;
192-
const sql = `SELECT 1 FROM read_parquet('${url}') LIMIT 1`;
193-
await executeQuery(sql);
194-
return true;
195-
} catch (error) {
196-
console.warn(`Data source '${root}' probe failed:`, error);
197-
return false;
191+
// Try up to 3 files from the end (latest may not exist with fallback list)
192+
const candidates = files.slice(-3).reverse();
193+
for (const file of candidates) {
194+
try {
195+
const url = `${DATA_ROOTS[root]}${PATH_PREFIX}${file.filename}`;
196+
const sql = `SELECT 1 FROM read_parquet('${url}') LIMIT 1`;
197+
await executeQuery(sql);
198+
return true;
199+
} catch (error) {
200+
console.warn(`Data source '${root}' probe failed for ${file.filename}:`, error);
201+
}
198202
}
203+
return false;
199204
}
200205

201206
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)