Skip to content

Commit

Permalink
refactor: add onGetFiles to renderer IPC (#1450)
Browse files Browse the repository at this point in the history
* chore: add missing type to ambient.d.ts

* refactor: return localPath from getFiles

* refactor: move PackageJsonOptions to interfaces.ts

* refactor: add IPC event to get file content from renderer
  • Loading branch information
dsanders11 authored Aug 24, 2023
1 parent 8f8ec0d commit e9a26b5
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 27 deletions.
11 changes: 10 additions & 1 deletion src/ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { ReleaseInfo } from '@electron/fiddle-core';
import { ReleaseInfo, SemVer } from '@electron/fiddle-core';
import * as MonacoType from 'monaco-editor';

import {
BisectRequest,
BlockableAccelerator,
EditorValues,
FiddleEvent,
FileTransformOperation,
Files,
IPackageManager,
InstallState,
MessageOptions,
NodeTypes,
OutputEntry,
PMOperationOptions,
PackageJsonOptions,
RunResult,
RunnableVersion,
SelectedLocalVersion,
Expand Down Expand Up @@ -116,6 +119,12 @@ declare global {
isReleasedMajor(major: number): Promise<boolean>;
macTitlebarClicked(): void;
monaco: typeof MonacoType;
onGetFiles(
callback: (
options: PackageJsonOptions | undefined,
transforms: Array<FileTransformOperation>,
) => Promise<{ localPath?: string; files: Files }>,
);
openThemeFolder(): Promise<void>;
packageRun(
{ dir, packageManager }: PMOperationOptions,
Expand Down
5 changes: 5 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,8 @@ export enum AppStateBroadcastMessageType {
export type NodeTypeDTS = `${string}.d.ts`;

export type NodeTypes = Record<NodeTypeDTS, string>;

export interface PackageJsonOptions {
includeElectron?: boolean;
includeDependencies?: boolean;
}
1 change: 1 addition & 0 deletions src/ipc-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export enum IpcEvents {
GET_NODE_TYPES = 'GET_NODE_TYPES',
CLEANUP_DIRECTORY = 'CLEANUP_DIRECTORY',
DELETE_USER_DATA = 'DELETE_USER_DATA',
GET_FILES = 'GET_FILES',
}

export const ipcMainEvents = [
Expand Down
26 changes: 26 additions & 0 deletions src/main/utils/get-files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MessageChannelMain } from 'electron';

import { FileTransformOperation, Files } from '../../interfaces';
import { IpcEvents } from '../../ipc-events';
import { ipcMainManager } from '../ipc';

/**
* Gets file content from the renderer
*/
export function getFiles(
transforms: Array<FileTransformOperation>,
): Promise<{ localPath?: string; files: Files }> {
return new Promise((resolve) => {
const { port1, port2 } = new MessageChannelMain();
ipcMainManager.postMessage(
IpcEvents.GET_FILES,
{ options: undefined, transforms },
[port1],
);
port2.once('message', (event) => {
resolve(event.data);
port2.close();
});
port2.start();
});
}
22 changes: 21 additions & 1 deletion src/preload/preload.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// Remember to update ambient.d.ts for extending window object
import { IpcRendererEvent, ipcRenderer } from 'electron';

import { FiddleEvent } from '../interfaces';
import {
FiddleEvent,
FileTransformOperation,
Files,
PackageJsonOptions,
} from '../interfaces';
import { IpcEvents, WEBCONTENTS_READY_FOR_IPC_SIGNAL } from '../ipc-events';
import { FiddleTheme } from '../themes-defaults';

Expand Down Expand Up @@ -139,6 +144,21 @@ export async function setupFiddleGlobal() {
ipcRenderer.send(IpcEvents.CLICK_TITLEBAR_MAC);
},
monaco: null as any, // will be set in main.tsx
onGetFiles(
callback: (
options: PackageJsonOptions | undefined,
transforms: Array<FileTransformOperation>,
) => Promise<{ localPath?: string; files: Files }>,
) {
ipcRenderer.removeAllListeners(IpcEvents.GET_FILES);
ipcRenderer.on(
IpcEvents.GET_FILES,
async (e, { options, transforms }) => {
const { localPath, files } = await callback(options, transforms);
e.ports[0].postMessage({ localPath, files: [...files.entries()] });
},
);
},
async openThemeFolder() {
await ipcRenderer.invoke(IpcEvents.OPEN_THEME_FOLDER);
},
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { Runner } from './runner';
import { AppState } from './state';
import { TaskRunner } from './task-runner';
import { activateTheme, getTheme } from './themes';
import { PackageJsonOptions, getPackageJson } from './utils/get-package';
import { getPackageJson } from './utils/get-package';
import { getElectronVersions } from './versions';
import {
EditorId,
EditorValues,
PACKAGE_NAME,
PackageJsonOptions,
SetFiddleOptions,
} from '../interfaces';
import { defaultDark, defaultLight } from '../themes-defaults';
Expand Down
16 changes: 10 additions & 6 deletions src/renderer/file-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AppState } from './state';
import { dotfilesTransform } from './transforms/dotfiles';
import { forgeTransform } from './transforms/forge';
import { isKnownFile } from './utils/editor-utils';
import { DEFAULT_OPTIONS, PackageJsonOptions } from './utils/get-package';
import { DEFAULT_OPTIONS } from './utils/get-package';
import {
EditorId,
EditorValues,
Expand All @@ -16,10 +16,12 @@ import {
Files,
GenericDialogType,
PACKAGE_NAME,
PackageJsonOptions,
} from '../interfaces';

export class FileManager {
constructor(private readonly appState: AppState) {
this.getFiles = this.getFiles.bind(this);
this.openFiddle = this.openFiddle.bind(this);
this.saveFiddle = this.saveFiddle.bind(this);

Expand Down Expand Up @@ -48,6 +50,8 @@ export class FileManager {
window.ElectronFiddle.addEventListener('save-fiddle-forge', (filePath) => {
this.saveFiddle(filePath, ['dotfiles', 'forge']);
});

window.ElectronFiddle.onGetFiles(this.getFiles);
}

/**
Expand Down Expand Up @@ -132,7 +136,7 @@ export class FileManager {
if (!pathToSave) {
window.ElectronFiddle.showSaveDialog();
} else {
const files = await this.getFiles(undefined, transforms);
const { files } = await this.getFiles(undefined, transforms);

for (const [fileName, content] of files) {
const savePath = path.join(pathToSave, fileName);
Expand Down Expand Up @@ -161,13 +165,13 @@ export class FileManager {
*
* @param {PackageJsonOptions} [options]
* @param {Array<FileTransformOperation>} [transforms]
* @returns {Promise<Files>}
* @returns {Promise<{ localPath: string; files: Files }>}
* @memberof FileManager
*/
public async getFiles(
options?: PackageJsonOptions,
transforms: Array<FileTransformOperation> = [],
): Promise<Files> {
): Promise<{ localPath?: string; files: Files }> {
const { app } = window.ElectronFiddle;

const pOptions = typeof options === 'object' ? options : DEFAULT_OPTIONS;
Expand Down Expand Up @@ -196,7 +200,7 @@ export class FileManager {
}
}

return output;
return { localPath: app.state.localPath, files: output };
}

/**
Expand All @@ -212,7 +216,7 @@ export class FileManager {
transforms?: Array<FileTransformOperation>,
): Promise<string> {
const tmp = await import('tmp');
const files = await this.getFiles(options, transforms);
const { files } = await this.getFiles(options, transforms);
const dir = tmp.dirSync({
prefix: 'electron-fiddle',
});
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { Installer } from '@electron/fiddle-core';

import { Bisector } from './bisect';
import { AppState } from './state';
import { PackageJsonOptions } from './utils/get-package';
import { maybePlural } from './utils/plural-maybe';
import {
FileTransformOperation,
InstallState,
PMOperationOptions,
PackageJsonOptions,
RunResult,
RunnableVersion,
} from '../interfaces';
Expand Down
7 changes: 1 addition & 6 deletions src/renderer/utils/get-package.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import * as fiddlePackageJSON from '../../../package.json';
import { MAIN_JS } from '../../interfaces';
import { MAIN_JS, PackageJsonOptions } from '../../interfaces';
import { AppState } from '../../renderer/state';

export interface PackageJsonOptions {
includeElectron?: boolean;
includeDependencies?: boolean;
}

export const DEFAULT_OPTIONS = {
includeElectron: true,
includeDependencies: true,
Expand Down
1 change: 1 addition & 0 deletions tests/mocks/electron-fiddle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class ElectronFiddleMock {
public getUsername = jest.fn();
public macTitlebarClicked = jest.fn();
public monaco = new MonacoMock();
public onGetFiles = jest.fn();
public openThemeFolder = jest.fn();
public packageRun = jest.fn();
public platform = process.platform;
Expand Down
7 changes: 4 additions & 3 deletions tests/renderer/app-spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mocked } from 'jest-mock';
import * as semver from 'semver';

import { EditorValues, MAIN_JS, SetFiddleOptions } from '../../src/interfaces';
import { App } from '../../src/renderer/app';
Expand Down Expand Up @@ -33,9 +34,9 @@ describe('App component', () => {
});
mocked(window.ElectronFiddle.readThemeFile).mockResolvedValue(defaultDark);
mocked(window.ElectronFiddle.getReleasedVersions).mockReturnValue([]);
mocked(window.ElectronFiddle.getLatestStable).mockReturnValue({
version: '24.0.0',
});
mocked(window.ElectronFiddle.getLatestStable).mockReturnValue(
semver.parse('24.0.0')!,
);

({ ElectronFiddle } = window);
const { app: appMock } = ElectronFiddle;
Expand Down
13 changes: 8 additions & 5 deletions tests/renderer/file-manager-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ describe('FileManager', () => {
});

it(`always inserts ${PACKAGE_NAME}`, async () => {
expect(await fm.getFiles()).toStrictEqual(expected);
const { files } = await fm.getFiles();
expect(files).toStrictEqual(expected);
});

it('includes supported files', async () => {
Expand All @@ -244,19 +245,21 @@ describe('FileManager', () => {
const values = { ...editorValues, [file]: content };

app.getEditorValues.mockReturnValue(values);
expect((await fm.getFiles()).get(file)).toStrictEqual(content);
const { files } = await fm.getFiles();
expect(files.get(file)).toStrictEqual(content);
});

it('applies transforms', async () => {
const transformed: Files = new Map([['👉', '👈']]);
mocked(dotfilesTransform).mockResolvedValue(transformed);
expect(await fm.getFiles(undefined, ['dotfiles'])).toBe(transformed);
const { files } = await fm.getFiles(undefined, ['dotfiles']);
expect(files).toBe(transformed);
});

it('handles transform error', async () => {
mocked(dotfilesTransform).mockRejectedValue(new Error('💩'));
const result = await fm.getFiles(undefined, ['dotfiles']);
expect(result).toStrictEqual(expected);
const { files } = await fm.getFiles(undefined, ['dotfiles']);
expect(files).toStrictEqual(expected);
});
});
});
7 changes: 4 additions & 3 deletions tests/renderer/versions-spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mocked } from 'jest-mock';
import * as semver from 'semver';

import {
ElectronReleaseChannel,
Expand Down Expand Up @@ -34,9 +35,9 @@ describe('versions', () => {

it('uses the newest stable as a fallback', () => {
mocked(localStorage.getItem).mockReturnValue(null);
mocked(window.ElectronFiddle.getLatestStable).mockReturnValue({
version: '13.0.0',
});
mocked(window.ElectronFiddle.getLatestStable).mockReturnValue(
semver.parse('13.0.0')!,
);
const output = getDefaultVersion([
{ version: '11.0.0' },
{ version: '15.0.0-nightly.20210715' },
Expand Down

0 comments on commit e9a26b5

Please sign in to comment.