diff --git a/src/components/App/client-api.ts b/src/components/App/client-api.ts new file mode 100644 index 00000000..3dc465ea --- /dev/null +++ b/src/components/App/client-api.ts @@ -0,0 +1,37 @@ +import App from './index'; + +import { expose } from 'comlink'; + +export function exposeAPI(app: App) { + self.parent.postMessage('READY', '*'); + self.addEventListener('message', (ev: MessageEvent) => { + if (ev.data !== 'READY?') { + return; + } + ev.stopPropagation(); + self.parent.postMessage('READY', '*'); + }); + expose(new API(app), self.parent); +} + +class API { + constructor(private app: App) { } + + async setFile(blob: Blob, name: string) { + await new Promise((resolve) => { + this.app.setState({ file: new File([blob], name) }, resolve); + }); + await new Promise((resolve) => { + document.addEventListener('squooshingdone', resolve, { once: true }); + }); + } + + async getBlob(side: 0 | 1) { + if (!this.app.state.file || !this.app.compressInstance) { + throw new Error('No file has been loaded'); + } + + await this.app.compressInstance.compressionJobs[side]; + return this.app.compressInstance.state.images[side].file; + } +} diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 0e5a1e9d..7d4e3ded 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -36,7 +36,7 @@ export default class App extends Component { file: undefined, Compress: undefined, }; - private compressInstance?: import('../compress').default; + compressInstance?: import('../compress').default; snackbar?: SnackBarElement; @@ -70,7 +70,7 @@ export default class App extends Component { }); window.addEventListener('popstate', this.onPopState); - this.exposeAPI(); + import('./client-api').then(m => m.exposeAPI(this)); } @bind @@ -105,39 +105,6 @@ export default class App extends Component { this.setState({ isEditorOpen: true }); } - private exposeAPI() { - const api = { - setFile: async (blob: Blob, name: string) => { - let oldCompressorState = this.compressInstance && this.compressInstance.state; - await new Promise((resolve) => { - this.setState({ file: new File([blob], name) }, resolve); - }); - await new Promise((resolve) => { - document.addEventListener('squooshingdone', resolve, { once: true }); - }); - if (oldCompressorState) { - let newState = this.compressInstance!.state; - [0, 1].forEach((index) => { - oldCompressorState = cleanMerge(oldCompressorState!, `images.${index}`, { - loading: false, - data: undefined, - }); - newState = cleanSet(newState, `images.${index}`, oldCompressorState.images[index]); - }); - this.compressInstance!.setState(newState); - } - }, - getBlob: async (side: 0 | 1) => { - if (!this.state.file || !this.compressInstance) { - throw new Error('No file has been loaded'); - } - await this.compressInstance.compressionJobs[side]; - return this.compressInstance.state.images[side].file; - }, - }; - expose(api, self.parent); - } - render({}: Props, { file, isEditorOpen, Compress }: State) { return (