import type {
Thenable,
FulfilledThenable,
RejectedThenable,
} from 'shared/ReactTypes';
import type {TimelineData} from './types';
import * as React from 'react';
import {importFile as importFileWorker} from './import-worker';
const fileNameToProfilerDataMap: Map<
string,
Thenable<TimelineData>,
> = new Map();
function readRecord<T>(record: Thenable<T>): T | Error {
if (typeof React.use === 'function') {
try {
return React.use(record);
} catch (x) {
if (record.status === 'rejected') {
return (record.reason: any);
}
throw x;
}
}
if (record.status === 'fulfilled') {
return record.value;
} else if (record.status === 'rejected') {
return (record.reason: any);
} else {
throw record;
}
}
export function importFile(file: File): TimelineData | Error {
const fileName = file.name;
let record = fileNameToProfilerDataMap.get(fileName);
if (!record) {
const callbacks = new Set<(value: any) => mixed>();
const rejectCallbacks = new Set<(reason: mixed) => mixed>();
const thenable: Thenable<TimelineData> = {
status: 'pending',
value: null,
reason: null,
then(callback: (value: any) => mixed, reject: (error: mixed) => mixed) {
callbacks.add(callback);
rejectCallbacks.add(reject);
},
displayName: `Importing file "${fileName}"`,
};
const wake = () => {
callbacks.forEach(callback => callback((thenable: any).value));
callbacks.clear();
rejectCallbacks.clear();
};
const wakeRejections = () => {
rejectCallbacks.forEach(callback => callback((thenable: any).reason));
rejectCallbacks.clear();
callbacks.clear();
};
record = thenable;
importFileWorker(file).then(data => {
switch (data.status) {
case 'SUCCESS':
const fulfilledThenable: FulfilledThenable<TimelineData> =
(thenable: any);
fulfilledThenable.status = 'fulfilled';
fulfilledThenable.value = data.processedData;
wake();
break;
case 'INVALID_PROFILE_ERROR':
case 'UNEXPECTED_ERROR':
const rejectedThenable: RejectedThenable<TimelineData> =
(thenable: any);
rejectedThenable.status = 'rejected';
rejectedThenable.reason = data.error;
wakeRejections();
break;
}
});
fileNameToProfilerDataMap.set(fileName, record);
}
const response = readRecord(record);
return response;
}