Skip to content

Commit

Permalink
refactor: remove Sync() calls from readFiddle() (#761)
Browse files Browse the repository at this point in the history
Trying to reduce startup jank by making some blocking calls yield.
  • Loading branch information
ckerr committed Jul 12, 2021
1 parent 6f9e6b1 commit 97392be
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 28 deletions.
32 changes: 16 additions & 16 deletions src/utils/read-fiddle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ import * as path from 'path';
export async function readFiddle(folder: string): Promise<EditorValues> {
const got: EditorValues = {};

const tryRead = (name: string) => {
try {
const filename = path.join(folder, name);
const content = fs.readFileSync(filename, 'utf-8');
return content || '';
} catch (error) {
console.warn(`Could not read file ${name}:`, error);
return '';
}
};
try {
const names = (await fs.readdir(folder)).filter(isSupportedFile);
const values = await Promise.allSettled(
names.map((name) => fs.readFile(path.join(folder, name), 'utf8')),
);

for (let i = 0; i < names.length; ++i) {
const name = names[i];
const value = values[i];

if (!fs.existsSync(folder)) {
console.warn(`readFiddle(): "${folder}" does not exist`);
} else {
for (const file of fs.readdirSync(folder)) {
if (isSupportedFile(file)) {
got[file] = tryRead(file);
if (value.status === 'fulfilled') {
got[name] = value.value || '';
} else {
console.warn(`Could not read file ${name}:`, value.reason);
got[name] = '';
}
}
} catch (err) {
console.warn(`Unable to read "${folder}": ${err.toString()}`);
}

if (!(MAIN_JS in got)) {
Expand Down
20 changes: 9 additions & 11 deletions tests/utils/read-fiddle-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ describe('read-fiddle', () => {
const folder = '/some/place';

beforeEach(() => {
(fs.existsSync as jest.Mock).mockImplementationOnce(() => true);
(fs.readFileSync as jest.Mock).mockImplementation((filename) => filename);
(fs.readFile as jest.Mock).mockImplementation((filename) =>
Promise.resolve(filename),
);
console.warn = jest.fn();
});

Expand All @@ -20,11 +21,10 @@ describe('read-fiddle', () => {
});

function setupFSMocks(editorValues: EditorValues) {
(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.readdirSync as jest.Mock).mockReturnValue(Object.keys(editorValues));
(fs.readFileSync as jest.Mock).mockImplementation((filename) => {
return editorValues[path.basename(filename)];
});
(fs.readdir as jest.Mock).mockResolvedValue(Object.keys(editorValues));
(fs.readFile as jest.Mock).mockImplementation((filename) =>
Promise.resolve(editorValues[path.basename(filename)]),
);
}

it('injects main.js if not present', async () => {
Expand Down Expand Up @@ -67,9 +67,7 @@ describe('read-fiddle', () => {
it('handles read errors gracefully', async () => {
const mockValues = createEditorValues();
setupFSMocks(mockValues);
(fs.readFileSync as jest.Mock).mockImplementation(() => {
throw new Error('bwap');
});
(fs.readFile as jest.Mock).mockRejectedValue(new Error('bwap'));

const files = await readFiddle(folder);

Expand All @@ -82,7 +80,7 @@ describe('read-fiddle', () => {
it('ensures truthy even when read returns null', async () => {
const mockValues = createEditorValues();
setupFSMocks(mockValues);
(fs.readFileSync as jest.Mock).mockReturnValue(null);
(fs.readFile as jest.Mock).mockResolvedValue(null);

const files = await readFiddle(folder);

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"preserveConstEnums": true,
"sourceMap": true,
"lib": [
"es2019",
"es2020",
"dom",
"WebWorker"
],
Expand Down

0 comments on commit 97392be

Please sign in to comment.