feat(electron-eventa): new package

This commit is contained in:
Neko Ayaka
2026-02-28 00:49:38 +08:00
parent c0f05c8827
commit 9ffebd236b
11 changed files with 217 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# @proj-airi/electron-eventa
Shared Eventa contract definitions for Electron IPC across AIRI apps.
## Exports
- `@proj-airi/electron-eventa`: core Electron contracts (`electron`, `bounds`, `cursorScreenPoint`, etc.)
- `@proj-airi/electron-eventa/electron-updater`: auto-updater contracts and state types
+37
View File
@@ -0,0 +1,37 @@
{
"name": "@proj-airi/electron-eventa",
"type": "module",
"version": "0.8.5-beta.3",
"private": true,
"description": "Shared Eventa contracts for Electron IPC",
"author": {
"name": "Moeru AI Project AIRI Team",
"email": "airi@moeru.ai",
"url": "https://github.com/moeru-ai"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/moeru-ai/airi.git",
"directory": "packages/electron-eventa"
},
"exports": {
".": "./dist/index.mjs",
"./electron": "./dist/electron/index.mjs",
"./electron-updater": "./dist/electron-updater/index.mjs",
"./package.json": "./package.json"
},
"types": "./dist/index.d.mts",
"scripts": {
"dev": "pnpm run build",
"build": "tsdown",
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"electron": ">=39 <41"
},
"dependencies": {
"@moeru/eventa": "^1.0.0-beta.1",
"builder-util-runtime": "catalog:"
}
}
@@ -0,0 +1,40 @@
import type { UpdateInfo } from 'builder-util-runtime'
import { defineEventa, defineInvokeEventa } from '@moeru/eventa'
export type AutoUpdaterStatus
= | 'idle'
| 'disabled'
| 'checking'
| 'available'
| 'not-available'
| 'downloading'
| 'downloaded'
| 'error'
export interface AutoUpdaterProgress {
percent: number
bytesPerSecond: number
transferred: number
total: number
}
export interface AutoUpdaterError {
message: string
}
export interface AutoUpdaterState {
status: AutoUpdaterStatus
info?: Omit<UpdateInfo, 'path' | 'sha512'>
progress?: AutoUpdaterProgress
error?: AutoUpdaterError
}
export const electronAutoUpdaterStateChanged = defineEventa<AutoUpdaterState>('eventa:event:electron:auto-updater:state-changed')
export const autoUpdater = {
getState: defineInvokeEventa<AutoUpdaterState>('eventa:invoke:electron:auto-updater:get-state'),
checkForUpdates: defineInvokeEventa<AutoUpdaterState>('eventa:invoke:electron:auto-updater:check-for-updates'),
downloadUpdate: defineInvokeEventa<AutoUpdaterState>('eventa:invoke:electron:auto-updater:download-update'),
quitAndInstall: defineInvokeEventa<void>('eventa:invoke:electron:auto-updater:quit-and-install'),
}
@@ -0,0 +1,11 @@
import { defineInvokeEventa } from '@moeru/eventa'
const isMacOS = defineInvokeEventa<boolean>('eventa:invoke:electron:app:is-macos')
const isWindows = defineInvokeEventa<boolean>('eventa:invoke:electron:app:is-windows')
const isLinux = defineInvokeEventa<boolean>('eventa:invoke:electron:app:is-linux')
export const app = {
isMacOS,
isWindows,
isLinux,
}
@@ -0,0 +1,15 @@
import { app } from './app'
import { screen } from './screen'
import { systemPreferences } from './system-preferences'
import { window } from './window'
export { cursorScreenPoint, startLoopGetCursorScreenPoint } from './screen'
export { bounds, startLoopGetBounds } from './window'
export type { BackgroundMaterialType, ResizeDirection, VibrancyType } from './window'
export const electron = {
screen,
window,
systemPreferences,
app,
}
@@ -0,0 +1,24 @@
import type { Display, screen as electronScreen, Point } from 'electron'
import { defineEventa, defineInvokeEventa } from '@moeru/eventa'
export const cursorScreenPoint = defineEventa<Point>('eventa:event:electron:screen:cursor-screen-point')
export const startLoopGetCursorScreenPoint = defineInvokeEventa('eventa:event:electron:screen:start-loop-get-cursor-screen-point')
const getAllDisplays = defineInvokeEventa<Display[]>('eventa:invoke:electron:screen:get-all-displays')
const getPrimaryDisplay = defineInvokeEventa<Display>('eventa:invoke:electron:screen:get-primary-display')
const getCursorScreenPoint = defineInvokeEventa<ReturnType<typeof electronScreen.getCursorScreenPoint>>('eventa:invoke:electron:screen:get-cursor-screen-point')
const dipToScreenPoint = defineInvokeEventa<ReturnType<typeof electronScreen.dipToScreenPoint>, Parameters<typeof electronScreen.dipToScreenPoint>[0]>('eventa:invoke:electron:screen:dip-to-screen-point')
const dipToScreenRect = defineInvokeEventa<ReturnType<typeof electronScreen.dipToScreenRect>, Parameters<typeof electronScreen.dipToScreenRect>[1]>('eventa:invoke:electron:screen:dip-to-screen-rect')
const screenToDipPoint = defineInvokeEventa<ReturnType<typeof electronScreen.screenToDipPoint>, Parameters<typeof electronScreen.screenToDipPoint>[0]>('eventa:invoke:electron:screen:screen-to-dip-point')
const screenToDipRect = defineInvokeEventa<ReturnType<typeof electronScreen.screenToDipRect>, Parameters<typeof electronScreen.screenToDipRect>[1]>('eventa:invoke:electron:screen:screen-to-dip-rect')
export const screen = {
getAllDisplays,
getPrimaryDisplay,
getCursorScreenPoint,
dipToScreenPoint,
dipToScreenRect,
screenToDipPoint,
screenToDipRect,
}
@@ -0,0 +1,14 @@
import type { systemPreferences as electronSystemPreferences } from 'electron'
import { defineInvokeEventa } from '@moeru/eventa'
type MediaAccessStatusRequest = ['microphone' | 'camera' | 'screen']
type AskForMediaAccessRequest = ['microphone' | 'camera']
const getMediaAccessStatus = defineInvokeEventa<ReturnType<typeof electronSystemPreferences.getMediaAccessStatus>, MediaAccessStatusRequest>('eventa:invoke:electron:system-preferences:get-media-access-status')
const askForMediaAccess = defineInvokeEventa<ReturnType<typeof electronSystemPreferences.askForMediaAccess>, AskForMediaAccessRequest>('eventa:invoke:electron:system-preferences:ask-for-media-access')
export const systemPreferences = {
getMediaAccessStatus,
askForMediaAccess,
}
@@ -0,0 +1,26 @@
import type { BrowserWindow, Rectangle } from 'electron'
import { defineEventa, defineInvokeEventa } from '@moeru/eventa'
export const bounds = defineEventa<Rectangle>('eventa:event:electron:window:bounds')
export const startLoopGetBounds = defineInvokeEventa('eventa:event:electron:window:start-loop-get-bounds')
const getBounds = defineInvokeEventa<ReturnType<BrowserWindow['getBounds']>>('eventa:invoke:electron:window:get-bounds')
const setBounds = defineInvokeEventa<void, Parameters<BrowserWindow['setBounds']>>('eventa:invoke:electron:window:set-bounds')
const setIgnoreMouseEvents = defineInvokeEventa<void, [boolean, { forward: boolean }]>('eventa:invoke:electron:window:set-ignore-mouse-events')
const setVibrancy = defineInvokeEventa<void, Parameters<BrowserWindow['setVibrancy']>>('eventa:invoke:electron:window:set-vibrancy')
const setBackgroundMaterial = defineInvokeEventa<void, Parameters<BrowserWindow['setBackgroundMaterial']>>('eventa:invoke:electron:window:set-background-material')
const resize = defineInvokeEventa<void, { deltaX: number, deltaY: number, direction: ResizeDirection }>('eventa:invoke:electron:window:resize')
export type VibrancyType = Parameters<BrowserWindow['setVibrancy']>[0]
export type BackgroundMaterialType = Parameters<BrowserWindow['setBackgroundMaterial']>[0]
export type ResizeDirection = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw'
export const window = {
getBounds,
setBounds,
setIgnoreMouseEvents,
setVibrancy,
setBackgroundMaterial,
resize,
}
+12
View File
@@ -0,0 +1,12 @@
export {
bounds,
cursorScreenPoint,
startLoopGetBounds,
startLoopGetCursorScreenPoint,
} from './electron/index'
export type {
BackgroundMaterialType,
ResizeDirection,
VibrancyType,
} from './electron/index'
export { electron } from './electron/index'
+19
View File
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext",
"DOM"
],
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
+11
View File
@@ -0,0 +1,11 @@
import { defineConfig } from 'tsdown'
export default defineConfig({
entry: [
'./src/index.ts',
'./src/electron/index.ts',
'./src/electron-updater/index.ts',
],
dts: true,
format: 'esm',
})