fix: stabilize market metrics hydration and sorting
This commit is contained in:
@@ -10,6 +10,7 @@ interface ExportRangeControllerOptions {
|
||||
onProgress?: (state: { currentPage: number; totalPages?: number }) => void;
|
||||
prepareCurrentPageForExport(): Promise<void>;
|
||||
readCurrentPageRecords(): MarketRecord[];
|
||||
readCurrentPageRowCount(): number;
|
||||
window: Window;
|
||||
}
|
||||
|
||||
@@ -26,13 +27,10 @@ export function createExportRangeController(options: ExportRangeControllerOption
|
||||
currentPage,
|
||||
totalPages: target.mode === "count" ? target.pageCount : undefined
|
||||
});
|
||||
const currentPageReady = await waitForCurrentPageReady(expectedMinimumRowCount);
|
||||
if (!currentPageReady) {
|
||||
const currentPageRecords = await preparePageRecords(expectedMinimumRowCount);
|
||||
if (!currentPageRecords) {
|
||||
throw new Error(`第 ${currentPage} 页加载超时,请稍后重试`);
|
||||
}
|
||||
|
||||
await options.prepareCurrentPageForExport();
|
||||
const currentPageRecords = options.readCurrentPageRecords();
|
||||
currentPageRecords.forEach((record) => {
|
||||
const existingRecord = mergedRecords.get(record.authorId);
|
||||
mergedRecords.set(record.authorId, mergeMarketRecord(existingRecord, record));
|
||||
@@ -63,6 +61,33 @@ export function createExportRangeController(options: ExportRangeControllerOption
|
||||
}
|
||||
};
|
||||
|
||||
async function preparePageRecords(
|
||||
expectedMinimumRowCount: number | undefined
|
||||
): Promise<MarketRecord[] | null> {
|
||||
for (let attempt = 0; attempt < 4; attempt += 1) {
|
||||
const currentPageReady = await waitForCurrentPageReady();
|
||||
if (!currentPageReady) {
|
||||
return null;
|
||||
}
|
||||
|
||||
await options.prepareCurrentPageForExport();
|
||||
const currentPageRecords = options.readCurrentPageRecords();
|
||||
if (
|
||||
currentPageRecords.length > 0 &&
|
||||
(
|
||||
typeof expectedMinimumRowCount !== "number" ||
|
||||
expectedMinimumRowCount <= 0 ||
|
||||
isCurrentPageTerminal() ||
|
||||
currentPageRecords.length >= expectedMinimumRowCount
|
||||
)
|
||||
) {
|
||||
return currentPageRecords;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function waitForPageChange(previousSignature: string): Promise<boolean> {
|
||||
const previousPageState = parsePageSignature(previousSignature);
|
||||
|
||||
@@ -82,9 +107,7 @@ export function createExportRangeController(options: ExportRangeControllerOption
|
||||
return false;
|
||||
}
|
||||
|
||||
async function waitForCurrentPageReady(
|
||||
expectedMinimumRowCount: number | undefined
|
||||
): Promise<boolean> {
|
||||
async function waitForCurrentPageReady(): Promise<boolean> {
|
||||
let stableAttemptCount = 0;
|
||||
let lastReadyFingerprint = "";
|
||||
|
||||
@@ -101,17 +124,6 @@ export function createExportRangeController(options: ExportRangeControllerOption
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof expectedMinimumRowCount === "number" &&
|
||||
expectedMinimumRowCount > 0 &&
|
||||
!pageState.isTerminalPage &&
|
||||
pageState.rowCount < expectedMinimumRowCount
|
||||
) {
|
||||
stableAttemptCount = 0;
|
||||
lastReadyFingerprint = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
const readyFingerprint = [
|
||||
pageState.pageToken,
|
||||
pageState.authorIds,
|
||||
@@ -146,9 +158,13 @@ export function createExportRangeController(options: ExportRangeControllerOption
|
||||
authorIds: pageSignature.authorIds,
|
||||
isTerminalPage: isPageControlDisabled(nextPageControl),
|
||||
pageToken: pageSignature.pageToken,
|
||||
rowCount: options.readCurrentPageRecords().length
|
||||
rowCount: options.readCurrentPageRowCount()
|
||||
};
|
||||
}
|
||||
|
||||
function isCurrentPageTerminal(): boolean {
|
||||
return isPageControlDisabled(findNextPageControl(options.document));
|
||||
}
|
||||
}
|
||||
|
||||
function parsePageSignature(signature: string): {
|
||||
|
||||
Reference in New Issue
Block a user