Skip to content

Commit

Permalink
refactor: update export names
Browse files Browse the repository at this point in the history
  • Loading branch information
mato533 committed Oct 23, 2024
1 parent c7d8b65 commit 0a10419
Show file tree
Hide file tree
Showing 21 changed files with 184 additions and 169 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"./main": {
"import": {
"types": "./dist/types/index.d.ts",
"types": "./dist/types/main.d.ts",
"default": "./dist/es/main.js"
},
"require": {
Expand All @@ -26,7 +26,7 @@
},
"./preload": {
"import": {
"types": "./dist/types/index.d.ts",
"types": "./dist/types/preload.d.ts",
"default": "./dist/es/preload.js"
},
"require": {
Expand Down
9 changes: 3 additions & 6 deletions playground/src/main/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { getContextMenuHandler } from './showContextMenu'

import type { IpcMainInvokeEvent } from 'electron'
import type {
IpcBridgeApiSenderTypeGenerator,
IpcBridgeApiTypeGenerator
} from 'electron-typed-ipc-bridge'
import type { IpcApiEmitterGenerator, IpcApiGenerator } from 'electron-typed-ipc-bridge/main'

export const api = {
invoke: {
Expand All @@ -26,5 +23,5 @@ export const api = {
}
}

export type IpcSenderType = IpcBridgeApiSenderTypeGenerator<typeof api>
export type IpcBridgeApi = IpcBridgeApiTypeGenerator<typeof api>
export type IpcApiEmitter = IpcApiEmitterGenerator<typeof api>
export type IpcApi = IpcApiGenerator<typeof api>
2 changes: 1 addition & 1 deletion playground/src/main/api/showContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const getContextMenuHandler = () => {
return Menu.getApplicationMenu()
}

return async (_e: IpcMainInvokeEvent) => {
return (_e: IpcMainInvokeEvent) => {
const menu = getMenu()
if (menu) {
menu!.popup()
Expand Down
4 changes: 2 additions & 2 deletions playground/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { api } from './api'
import { setMenu } from './menu'
import { MyLogger } from './logger'

import type { IpcSenderType } from './api'
import type { IpcApiEmitter } from './api'

function createWindow(api: IpcSenderType): void {
function createWindow(api: IpcApiEmitter): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
Expand Down
6 changes: 3 additions & 3 deletions playground/src/main/menu.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Menu, MenuItem } from 'electron'

import type { IpcSenderType } from './api'
import type { IpcApiEmitter } from './api'
import type { BrowserWindow } from 'electron'

const createMenu = (targetWindow: BrowserWindow, api: IpcSenderType) => {
const createMenu = (targetWindow: BrowserWindow, api: IpcApiEmitter) => {
return new MenuItem({
label: 'Test Message',
submenu: [
Expand All @@ -21,7 +21,7 @@ const createMenu = (targetWindow: BrowserWindow, api: IpcSenderType) => {
})
}

export const setMenu = (targetWindow: BrowserWindow, api: IpcSenderType) => {
export const setMenu = (targetWindow: BrowserWindow, api: IpcApiEmitter) => {
const appMenu = Menu.getApplicationMenu()
const menuItems = appMenu
? appMenu.items.concat([new MenuItem({ type: 'separator' })], createMenu(targetWindow, api))
Expand Down
4 changes: 2 additions & 2 deletions playground/src/preload/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ElectronAPI } from '@electron-toolkit/preload'
import type { IpcBridgeApi } from '../main/api'
import type { IpcApi } from '../main/api'

declare global {
interface Window {
electron: ElectronAPI
api: IpcBridgeApi
api: IpcApi
}
}
6 changes: 3 additions & 3 deletions playground/src/preload/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
import { AbstractLogger, getApiInvoker, initialise } from 'electron-typed-ipc-bridge/preload'
import { AbstractLogger, generateIpcApi, initialise } from 'electron-typed-ipc-bridge/preload'

import type { LogLevel } from 'electron-typed-ipc-bridge/preload'
import type { IpcBridgeApi } from '../main/api'
import type { IpcApi } from '../main/api'

// Custom APIs for renderer
class MyLogger extends AbstractLogger {
Expand All @@ -16,7 +16,7 @@ class MyLogger extends AbstractLogger {
initialise({ logger: { preload: new MyLogger() } })
// if disable looging, pass the empty object
// initialise({ logger: {} })
const api = await getApiInvoker<IpcBridgeApi>()
const api = await generateIpcApi<IpcApi>()

// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
Expand Down
4 changes: 2 additions & 2 deletions playground/src/renderer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ const handler = (event: MouseEvent) => {
event.preventDefault()
window.api.invoke.showContextMenu()
}
// handle message from main process
window.api.on.updateCounter((_e, value) => (counter.value = counter.value + value))
onMounted(() => {
window.addEventListener('contextmenu', handler)
// handle message from main process
window.api.on.updateCounter((_e, value) => (counter.value = counter.value + value))
})
onBeforeUnmount(() => {
Expand Down
12 changes: 8 additions & 4 deletions playground/src/renderer/src/components/Versions.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<script setup lang="ts">
import { reactive } from 'vue'
const versions = reactive({ ...window.electron.process.versions })
import { onMounted, ref } from 'vue'
const versions = ref()
onMounted(() => {
const _versions = window.electron.process.versions
console.log(_versions)
versions.value = { ..._versions }
})
</script>

<template>
<ul class="versions">
<ul v-if="versions" class="versions">
<li class="electron-version">Electron v{{ versions.electron }}</li>
<li class="chrome-version">Chromium v{{ versions.chrome }}</li>
<li class="node-version">Node v{{ versions.node }}</li>
Expand Down
1 change: 1 addition & 0 deletions playground/tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "../../../dist/types"],
"compilerOptions": {
"composite": true,
"moduleResolution": "Bundler",
"types": ["electron-vite/node"]
}
}
1 change: 1 addition & 0 deletions playground/tsconfig.web.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
],
"compilerOptions": {
"composite": true,
"moduleResolution": "Bundler",
"baseUrl": ".",
"paths": {
"@renderer/*": ["src/renderer/src/*"]
Expand Down
8 changes: 6 additions & 2 deletions rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ const defineConfig = (pkg: Record<string, any>) => {
]),
},
{
input: 'src/types/index.d.ts',
output: [{ file: pkg.types }],
input: {
index: 'src/types/index.d.ts',
main: 'src/types/main.d.ts',
preload: 'src/types/preload.d.ts',
},
output: [{ dir: dirname(pkg.types) }],
external,
onwarn: onwarnGenDts,
plugins: getPlugins([dts(), nodeExternals()]),
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/preload.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { getApiInvoker } from '../preload'
import { generateIpcApi } from '../preload'
import { API_CHANNEL_MAP } from '../channel'
import { registerIpcHandler } from '../main'

import type { IpcBridgeApiTypeGenerator } from '../preload'
import type { IpcApiGenerator } from '../preload'
import type { IpcMainInvokeEvent, IpcRendererEvent } from 'electron'

describe('preload', () => {
Expand Down Expand Up @@ -57,7 +57,7 @@ describe('preload', () => {
return channelMap
}
})
const _apiPreload = await getApiInvoker<IpcBridgeApiTypeGenerator<typeof _apiHandlers>>()
const _apiPreload = await generateIpcApi<IpcApiGenerator<typeof _apiHandlers>>()
_apiPreload.invoke.fn2('BOB')
expect(mocks.ipcRenderer.invoke).toHaveBeenLastCalledWith(channelMap.invoke.fn2, 'BOB')

Expand Down
30 changes: 13 additions & 17 deletions src/__tests__/types.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import type { BrowserWindow, IpcMainInvokeEvent, IpcRendererEvent } from 'electron'
import type {
IpcBridgeApiFunction,
IpcBridgeApiTypeGenerator,
IpcBridgeApiInvoker,
} from '../preload'
import type { IpcApiFunction, IpcApiGenerator, IpcApiInvoker } from '../preload'
import type { ApiChannelMapGenerator } from '../channel'
import type { IpcBridgeApiEmitterTypeGenerator } from '../main'
import type { IpcApiEmitterGenerator } from '../main'

describe('Type check', () => {
it('IpcBridgeApiFunction', () => {
it('IpcApiFunction', () => {
const _fn = (e: IpcMainInvokeEvent, arg1: string) => arg1
type ExpectedApiType = (arg1: string) => Promise<string>

expectTypeOf<ExpectedApiType>().toEqualTypeOf<IpcBridgeApiFunction<typeof _fn>>()
expectTypeOf<ExpectedApiType>().toEqualTypeOf<IpcApiFunction<typeof _fn>>()
})

it('IpcBridgeApiInvoker', () => {
it('IpcApiInvoker', () => {
const _apiHandlers = {
fn1: (e: IpcMainInvokeEvent) => console.log(e),
fn2: (_e: IpcMainInvokeEvent) => `hello`,
Expand All @@ -25,7 +21,7 @@ describe('Type check', () => {
},
}

type IpcBridgeApi = IpcBridgeApiInvoker<typeof _apiHandlers>
type IpcBridgeApi = IpcApiInvoker<typeof _apiHandlers>
type ExpectedType = {
fn1: () => Promise<void>
fn2: () => Promise<string>
Expand Down Expand Up @@ -87,7 +83,7 @@ describe('Type check', () => {
},
}

type TestTarget = IpcBridgeApiEmitterTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiEmitterGenerator<typeof _apiHandlers>
type ExpectedType = {
send: {
fn1: (window: BrowserWindow, arg1: string) => void
Expand All @@ -109,7 +105,7 @@ describe('Type check', () => {
},
}

type TestTarget = IpcBridgeApiEmitterTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiEmitterGenerator<typeof _apiHandlers>

expectTypeOf<undefined>().toEqualTypeOf<TestTarget>()
})
Expand All @@ -126,7 +122,7 @@ describe('Type check', () => {
},
}

type TestTarget = IpcBridgeApiEmitterTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiEmitterGenerator<typeof _apiHandlers>
type ExpectedType = {
send: {
fn1: (window: BrowserWindow, arg1: string) => void
Expand All @@ -141,7 +137,7 @@ describe('Type check', () => {
})
})

describe('IpcBridgeApiTypeGenerator', () => {
describe('IpcApiGenerator', () => {
it('invoke and on is existed', () => {
const _apiHandlers = {
invoke: {
Expand All @@ -161,7 +157,7 @@ describe('Type check', () => {
},
},
}
type TestTarget = IpcBridgeApiTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiGenerator<typeof _apiHandlers>
type ExpectedType = {
invoke: {
fn1: () => Promise<void>
Expand Down Expand Up @@ -194,7 +190,7 @@ describe('Type check', () => {
},
},
}
type TestTarget = IpcBridgeApiTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiGenerator<typeof _apiHandlers>
type ExpectedType = {
invoke: {
fn1: () => Promise<void>
Expand All @@ -219,7 +215,7 @@ describe('Type check', () => {
},
},
}
type TestTarget = IpcBridgeApiTypeGenerator<typeof _apiHandlers>
type TestTarget = IpcApiGenerator<typeof _apiHandlers>
type ExpectedType = {
on: {
fn1: (callback: (event: IpcRendererEvent, arg1: string) => void) => void
Expand Down
55 changes: 27 additions & 28 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,46 @@ import type { IpcMainInvokeEvent } from 'electron'
export const API_CHANNEL_MAP = `06675f7b-d88f-a064-d3ba-6a60dcbc091c` as const

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ApiOnFunction = (...args: any[]) => any
export type IpcApiOnFunction = (...args: any[]) => any

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ApiInvokeFunction = (event: IpcMainInvokeEvent, ...args: any[]) => any
export type IpcApiInvokeFunction = (event: IpcMainInvokeEvent, ...args: any[]) => any

export type ApiOnHandler = {
readonly [key: string]: ApiOnFunction | ApiOnHandler
export type IpcApiOnHandler = {
readonly [key: string]: IpcApiOnFunction | IpcApiOnHandler
}
export type ApiInvokeHandler = {
readonly [key: string]: ApiInvokeFunction | ApiInvokeHandler
export type IpcApiInvokeHandler = {
readonly [key: string]: IpcApiInvokeFunction | IpcApiInvokeHandler
}

export type ApiHandler = ApiInvokeHandler | ApiOnHandler
export type ApiFunction = ApiInvokeFunction | ApiOnFunction
export type IpcApiHandler = IpcApiInvokeHandler | IpcApiOnHandler
export type IpcApiFunction = IpcApiInvokeFunction | IpcApiOnFunction

export type IpcBridgeApiImplementation = {
on?: ApiOnHandler
invoke?: ApiInvokeHandler
export type IpcApiImplementation = {
on?: IpcApiOnHandler
invoke?: IpcApiInvokeHandler
}

type ApiChannelMapItem = {
[key: string]: string | ApiChannelMapItem
type IpcApiChannelMapItem = {
[key: string]: string | IpcApiChannelMapItem
}

type ApiChannelMapItemTypeGenerator<T extends ApiHandler> = {
[K in keyof T]: T[K] extends ApiFunction
type IpcApiChannelMapItemTypeGenerator<T extends IpcApiHandler> = {
[K in keyof T]: T[K] extends IpcApiFunction
? string
: T[K] extends ApiHandler
? ApiChannelMapItemTypeGenerator<T[K]>
: T[K] extends IpcApiHandler
? IpcApiChannelMapItemTypeGenerator<T[K]>
: never
}

export type ApiChannelMapGenerator<T extends IpcBridgeApiImplementation> = {
on: ApiChannelMapItemTypeGenerator<T['on']>
invoke: ApiChannelMapItemTypeGenerator<T['invoke']>
export type ApiChannelMapGenerator<T extends IpcApiImplementation> = {
on: IpcApiChannelMapItemTypeGenerator<T['on']>
invoke: IpcApiChannelMapItemTypeGenerator<T['invoke']>
}

let channelMap = undefined

export function haveSameStructure<T extends IpcBridgeApiImplementation>(
export function haveSameStructure<T extends IpcApiImplementation>(
obj1: T,
obj2: ApiChannelMapGenerator<T>
) {
Expand All @@ -68,16 +68,14 @@ export function haveSameStructure<T extends IpcBridgeApiImplementation>(
return keys1.every((key) => keys2.includes(key) && haveSameStructure(obj1[key], obj2[key]))
}

function getApiChannelMap<T extends IpcBridgeApiImplementation>(
apiHandlers: T
): ApiChannelMapGenerator<T>
function getApiChannelMap(apiHandlers: IpcBridgeApiImplementation) {
function getApiChannelMap<T extends IpcApiImplementation>(apiHandlers: T): ApiChannelMapGenerator<T>
function getApiChannelMap(apiHandlers: IpcApiImplementation) {
if (channelMap && haveSameStructure(apiHandlers, channelMap)) {
return channelMap
}

const _getApiChannelMap = (apiHandler: ApiHandler) => {
const channelMap: ApiChannelMapItem = {}
const _getApiChannelMap = (apiHandler: IpcApiHandler) => {
const channelMap: IpcApiChannelMapItem = {}
Object.keys(apiHandler).forEach((key) => {
if (typeof apiHandler[key] === 'object') {
channelMap[key] = _getApiChannelMap(apiHandler[key])
Expand All @@ -95,6 +93,7 @@ const MODE = {
invoke: 0,
on: 1,
} as const
export type ApiMode = (typeof MODE)[keyof typeof MODE]

export type IpcApiMode = (typeof MODE)[keyof typeof MODE]

export { getApiChannelMap, MODE }
Loading

0 comments on commit 0a10419

Please sign in to comment.