diff --git a/packages/electron-eventa/README.md b/packages/electron-eventa/README.md new file mode 100644 index 000000000..51cb92ae6 --- /dev/null +++ b/packages/electron-eventa/README.md @@ -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 diff --git a/packages/electron-eventa/package.json b/packages/electron-eventa/package.json new file mode 100644 index 000000000..58e2c737b --- /dev/null +++ b/packages/electron-eventa/package.json @@ -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:" + } +} diff --git a/packages/electron-eventa/src/electron-updater/index.ts b/packages/electron-eventa/src/electron-updater/index.ts new file mode 100644 index 000000000..79edae907 --- /dev/null +++ b/packages/electron-eventa/src/electron-updater/index.ts @@ -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 + progress?: AutoUpdaterProgress + error?: AutoUpdaterError +} + +export const electronAutoUpdaterStateChanged = defineEventa('eventa:event:electron:auto-updater:state-changed') + +export const autoUpdater = { + getState: defineInvokeEventa('eventa:invoke:electron:auto-updater:get-state'), + checkForUpdates: defineInvokeEventa('eventa:invoke:electron:auto-updater:check-for-updates'), + downloadUpdate: defineInvokeEventa('eventa:invoke:electron:auto-updater:download-update'), + quitAndInstall: defineInvokeEventa('eventa:invoke:electron:auto-updater:quit-and-install'), +} diff --git a/packages/electron-eventa/src/electron/app.ts b/packages/electron-eventa/src/electron/app.ts new file mode 100644 index 000000000..aa141be81 --- /dev/null +++ b/packages/electron-eventa/src/electron/app.ts @@ -0,0 +1,11 @@ +import { defineInvokeEventa } from '@moeru/eventa' + +const isMacOS = defineInvokeEventa('eventa:invoke:electron:app:is-macos') +const isWindows = defineInvokeEventa('eventa:invoke:electron:app:is-windows') +const isLinux = defineInvokeEventa('eventa:invoke:electron:app:is-linux') + +export const app = { + isMacOS, + isWindows, + isLinux, +} diff --git a/packages/electron-eventa/src/electron/index.ts b/packages/electron-eventa/src/electron/index.ts new file mode 100644 index 000000000..6657e13b5 --- /dev/null +++ b/packages/electron-eventa/src/electron/index.ts @@ -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, +} diff --git a/packages/electron-eventa/src/electron/screen.ts b/packages/electron-eventa/src/electron/screen.ts new file mode 100644 index 000000000..7587c2f40 --- /dev/null +++ b/packages/electron-eventa/src/electron/screen.ts @@ -0,0 +1,24 @@ +import type { Display, screen as electronScreen, Point } from 'electron' + +import { defineEventa, defineInvokeEventa } from '@moeru/eventa' + +export const cursorScreenPoint = defineEventa('eventa:event:electron:screen:cursor-screen-point') +export const startLoopGetCursorScreenPoint = defineInvokeEventa('eventa:event:electron:screen:start-loop-get-cursor-screen-point') + +const getAllDisplays = defineInvokeEventa('eventa:invoke:electron:screen:get-all-displays') +const getPrimaryDisplay = defineInvokeEventa('eventa:invoke:electron:screen:get-primary-display') +const getCursorScreenPoint = defineInvokeEventa>('eventa:invoke:electron:screen:get-cursor-screen-point') +const dipToScreenPoint = defineInvokeEventa, Parameters[0]>('eventa:invoke:electron:screen:dip-to-screen-point') +const dipToScreenRect = defineInvokeEventa, Parameters[1]>('eventa:invoke:electron:screen:dip-to-screen-rect') +const screenToDipPoint = defineInvokeEventa, Parameters[0]>('eventa:invoke:electron:screen:screen-to-dip-point') +const screenToDipRect = defineInvokeEventa, Parameters[1]>('eventa:invoke:electron:screen:screen-to-dip-rect') + +export const screen = { + getAllDisplays, + getPrimaryDisplay, + getCursorScreenPoint, + dipToScreenPoint, + dipToScreenRect, + screenToDipPoint, + screenToDipRect, +} diff --git a/packages/electron-eventa/src/electron/system-preferences.ts b/packages/electron-eventa/src/electron/system-preferences.ts new file mode 100644 index 000000000..8c2475bbe --- /dev/null +++ b/packages/electron-eventa/src/electron/system-preferences.ts @@ -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, MediaAccessStatusRequest>('eventa:invoke:electron:system-preferences:get-media-access-status') +const askForMediaAccess = defineInvokeEventa, AskForMediaAccessRequest>('eventa:invoke:electron:system-preferences:ask-for-media-access') + +export const systemPreferences = { + getMediaAccessStatus, + askForMediaAccess, +} diff --git a/packages/electron-eventa/src/electron/window.ts b/packages/electron-eventa/src/electron/window.ts new file mode 100644 index 000000000..155b42ddf --- /dev/null +++ b/packages/electron-eventa/src/electron/window.ts @@ -0,0 +1,26 @@ +import type { BrowserWindow, Rectangle } from 'electron' + +import { defineEventa, defineInvokeEventa } from '@moeru/eventa' + +export const bounds = defineEventa('eventa:event:electron:window:bounds') +export const startLoopGetBounds = defineInvokeEventa('eventa:event:electron:window:start-loop-get-bounds') + +const getBounds = defineInvokeEventa>('eventa:invoke:electron:window:get-bounds') +const setBounds = defineInvokeEventa>('eventa:invoke:electron:window:set-bounds') +const setIgnoreMouseEvents = defineInvokeEventa('eventa:invoke:electron:window:set-ignore-mouse-events') +const setVibrancy = defineInvokeEventa>('eventa:invoke:electron:window:set-vibrancy') +const setBackgroundMaterial = defineInvokeEventa>('eventa:invoke:electron:window:set-background-material') +const resize = defineInvokeEventa('eventa:invoke:electron:window:resize') + +export type VibrancyType = Parameters[0] +export type BackgroundMaterialType = Parameters[0] +export type ResizeDirection = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw' + +export const window = { + getBounds, + setBounds, + setIgnoreMouseEvents, + setVibrancy, + setBackgroundMaterial, + resize, +} diff --git a/packages/electron-eventa/src/index.ts b/packages/electron-eventa/src/index.ts new file mode 100644 index 000000000..a10f48a0f --- /dev/null +++ b/packages/electron-eventa/src/index.ts @@ -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' diff --git a/packages/electron-eventa/tsconfig.json b/packages/electron-eventa/tsconfig.json new file mode 100644 index 000000000..6869a6239 --- /dev/null +++ b/packages/electron-eventa/tsconfig.json @@ -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" + ] +} diff --git a/packages/electron-eventa/tsdown.config.ts b/packages/electron-eventa/tsdown.config.ts new file mode 100644 index 000000000..82bd636d9 --- /dev/null +++ b/packages/electron-eventa/tsdown.config.ts @@ -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', +})