diff --git a/packages/build/src/config.ts b/packages/build/src/config.ts index 3d14a332..31b08e4b 100644 --- a/packages/build/src/config.ts +++ b/packages/build/src/config.ts @@ -2,7 +2,7 @@ import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { root } from './root.ts' -export const threshold = 530_000 +export const threshold = 532_000 export const instantiations = 8000 diff --git a/packages/diff-view/src/parts/CommandMap/CommandMap.ts b/packages/diff-view/src/parts/CommandMap/CommandMap.ts index 0e207876..d600f1fe 100644 --- a/packages/diff-view/src/parts/CommandMap/CommandMap.ts +++ b/packages/diff-view/src/parts/CommandMap/CommandMap.ts @@ -17,6 +17,7 @@ import { handleContextMenu } from '../HandleContextMenu/HandleContextMenu.ts' import { handleCopy } from '../HandleCopy/HandleCopy.ts' import { handleCut } from '../HandleCut/HandleCut.ts' import { handleInput } from '../HandleInput/HandleInput.ts' +import { handleMessagePort } from '../HandleMessagePort/HandleMessagePort.ts' import { handlePaste } from '../HandlePaste/HandlePaste.ts' import { handleResize } from '../HandleResize/HandleResize.ts' import { handleSashPointerDown } from '../HandleSashPointerDown/HandleSashPointerDown.ts' @@ -66,6 +67,7 @@ export const commandMap = { 'DiffView.handleCopy': wrapCommand(handleCopy), 'DiffView.handleCut': wrapCommand(handleCut), 'DiffView.handleInput': wrapCommand(handleInput), + 'DiffView.handleMessagePort': handleMessagePort, 'DiffView.handlePaste': wrapCommand(handlePaste), 'DiffView.handleResize': wrapCommand(handleResize), 'DiffView.handleSashPointerDown': wrapCommand(handleSashPointerDown), diff --git a/packages/diff-view/src/parts/HandleMessagePort/HandleMessagePort.ts b/packages/diff-view/src/parts/HandleMessagePort/HandleMessagePort.ts new file mode 100644 index 00000000..b9a13608 --- /dev/null +++ b/packages/diff-view/src/parts/HandleMessagePort/HandleMessagePort.ts @@ -0,0 +1,7 @@ +import { PlainMessagePortRpc } from '@lvce-editor/rpc' +import * as RendererProcess from '../RendererProcess/RendererProcess.ts' + +export const handleMessagePort = async (port: any): Promise => { + const rpc = await PlainMessagePortRpc.create({ commandMap: {}, messagePort: port }) + RendererProcess.set(rpc) +} diff --git a/packages/diff-view/src/parts/Render2/Render2.ts b/packages/diff-view/src/parts/Render2/Render2.ts index fb90532c..3c6cfcf6 100644 --- a/packages/diff-view/src/parts/Render2/Render2.ts +++ b/packages/diff-view/src/parts/Render2/Render2.ts @@ -1,9 +1,18 @@ import * as ApplyRender from '../ApplyRender/ApplyRender.ts' import * as DiffViewStates from '../DiffViewStates/DiffViewStates.ts' +import * as RendererProcess from '../RendererProcess/RendererProcess.ts' -export const render2 = (uid: number, diffResult: readonly number[]): readonly any[] => { +export const render2 = (uid: number, diffResult: readonly number[]): readonly any[] | Promise => { const { newState, oldState } = DiffViewStates.get(uid) DiffViewStates.set(uid, newState, newState) const commands = ApplyRender.applyRender(oldState, newState, diffResult) - return commands + if (!RendererProcess.isConnected()) return commands + return renderDirect(uid, commands) +} + +const renderDirect = async (uid: number, commands: readonly any[]): Promise => { + const rendererWorkerCommands = commands.filter((command) => command[0] === 'Viewlet.setFocusContext') + const rendererProcessCommands = commands.filter((command) => command[0] !== 'Viewlet.setFocusContext') + const transactionId = await RendererProcess.invoke('Viewlet.queueCommands', uid, rendererProcessCommands) + return [...rendererWorkerCommands, ['Viewlet.commitPending', uid, transactionId]] } diff --git a/packages/diff-view/src/parts/RendererProcess/RendererProcess.ts b/packages/diff-view/src/parts/RendererProcess/RendererProcess.ts new file mode 100644 index 00000000..c2d7431c --- /dev/null +++ b/packages/diff-view/src/parts/RendererProcess/RendererProcess.ts @@ -0,0 +1,13 @@ +import type { Rpc } from '@lvce-editor/rpc' +import { RendererProcess as RendererProcessRegistry } from '@lvce-editor/rpc-registry' + +const state = { connected: false } +export const isConnected = (): boolean => { + const { connected } = state + return connected +} +export const invoke = (method: string, ...params: readonly unknown[]): Promise => RendererProcessRegistry.invoke(method, ...params) +export const set = (rpc: Rpc): void => { + RendererProcessRegistry.set(rpc) + state.connected = true +} diff --git a/packages/diff-view/test/HandleMessagePort.test.ts b/packages/diff-view/test/HandleMessagePort.test.ts new file mode 100644 index 00000000..8326cdf0 --- /dev/null +++ b/packages/diff-view/test/HandleMessagePort.test.ts @@ -0,0 +1,24 @@ +import { expect, jest, test } from '@jest/globals' +import { PlainMessagePortRpcParent } from '@lvce-editor/rpc' +import { RendererProcess as RendererProcessRegistry } from '@lvce-editor/rpc-registry' +import { handleMessagePort } from '../src/parts/HandleMessagePort/HandleMessagePort.ts' +import * as RendererProcess from '../src/parts/RendererProcess/RendererProcess.ts' + +declare const MessageChannel: { new (): any } + +test('connects the view directly to the renderer process', async () => { + const queueCommands = jest.fn((_uid: number, _commands: readonly unknown[]) => 31) + const { port1, port2 } = new MessageChannel() + const rendererProcessRpc = await PlainMessagePortRpcParent.create({ + commandMap: { 'Viewlet.queueCommands': queueCommands }, + messagePort: port1, + }) + + await handleMessagePort(port2) + expect(RendererProcess.isConnected()).toBe(true) + await expect(RendererProcess.invoke('Viewlet.queueCommands', 7, [['Viewlet.setDom2', 7, []]])).resolves.toBe(31) + expect(queueCommands).toHaveBeenCalledWith(7, [['Viewlet.setDom2', 7, []]]) + + await RendererProcessRegistry.dispose() + await rendererProcessRpc.dispose() +})