Skip to content

프론트엔드 API

This content is not available in your language yet.

CEF renderer의 V8 컨텍스트에 자동 주입되는 window.__suji__ 객체와 npm 래퍼.

┌────────────────────────┐
│ @suji/api (npm 래퍼) │ 권장 — 타입 안전 + JSON 자동 처리
└────────────┬───────────┘
│ wraps
┌────────────▼───────────┐
│ window.__suji__ │ raw 바인딩 — CEF가 V8 context에 주입
└────────────────────────┘
import { invoke, on, send, quit, platform } from '@suji/api';
const r = await invoke('ping'); // 객체 반환
const r2 = await invoke('greet', { name: 'Suji' });
const r3 = await invoke('ping', {}, { target: 'rust' }); // 특정 백엔드
const cancel = on('theme-changed', (data) => { ... });
send('clicked', { button: 'save' });
quit();
platform; // "macos" | "linux" | "windows"

주입된 전역. TypeScript 타입 없음, 모든 인자는 문자열이어야 함.

// invoke(channel: string, dataJSONString: string, optionsJSONString: string) → Promise<any>
await window.__suji__.invoke('ping', '{}', '{"target":"zig"}')
// core(requestJSONString: string) → Promise<any> — 코어 커맨드용
await window.__suji__.core(JSON.stringify({ cmd: 'create_window', title: 'X' }))
// send(channel, dataJSONString): void
window.__suji__.send('clicked', '{}')
// on(channel, callback): unsubscribeFn
const off = window.__suji__.on('event', (data) => { ... })
interface InvokeOptions {
target?: string; // 특정 백엔드 지정 ("zig" | "rust" | "go" | "node")
}
  • target 미지정 — 채널 이름으로 자동 라우팅 (백엔드가 handle(ch, ...) 등록한 것에 자동 매칭)
  • 같은 채널을 여러 백엔드가 등록한 경우 반드시 target 명시 (아니면 no handler 에러)

프레임워크 내장 기능. 백엔드 거치지 않고 Zig 코어가 직접 처리.

cmd파라미터응답
create_windowtitle, url?, name?, width?, height?{from:"zig-core", windowId:N}
set_titlewindowId, title{windowId:N, ok:bool}
set_boundswindowId, x?, y?, width?, height?{windowId:N, ok:bool}
fs_read_filepath{success:true,text}
fs_write_filepath, text{success:true}
fs_statpath{success:true,type,size,mtime}
fs_mkdirpath, recursive?{success:true}
fs_readdirpath{success:true,entries}
app_set_badge_countcount{success:bool,native:bool}
app_get_badge_count{count:N}
screen_get_all_displays{displays:[...]}
desktop_capturer_get_sourcestypes?{sources:[...]}
desktop_capturer_capture_thumbnailsourceId(screen:<id>:0/window:<id>:0), path{success:bool}
crash_reporter_startuploadToServer?, submitURL?, extra?{success:true,enabled:bool}
crash_reporter_get_parameters{parameters:{...}}
crash_reporter_add_extra_parameterkey, value{success:bool}
crash_reporter_remove_extra_parameterkey{success:bool}
crash_reporter_get_uploaded_reports{reports:[{id,date}]}
crash_reporter_get_last_crash_report{report:{id,date}|null}
quit{cmd:"quit"}
core_info{backends:[...]}

예:

const w = await window.__suji__.core(JSON.stringify({
cmd: 'create_window',
title: 'Settings',
name: 'settings', // 선택 — 백엔드에서 event.window.name으로 식별
url: 'http://localhost:12300/settings',
}));
console.log(w.windowId); // 2, 3, ...

@suji/api에서는 raw core 대신 typed wrapper를 권장:

import { fs } from '@suji/api';
await fs.mkdir('/tmp/suji', { recursive: true });
await fs.writeFile('/tmp/suji/hello.txt', 'hello');
const text = await fs.readFile('/tmp/suji/hello.txt');
ElectronSuji
ipcRenderer.invoke(ch, ...args)invoke(ch, data, options) — args 단일 객체
ipcRenderer.send(ch, data)send(ch, data)
ipcRenderer.on(ch, cb)on(ch, cb)
ipcRenderer.once(ch, cb)once(ch, cb)
app.quit()quit()
app.setBadgeCount(n) / app.getBadgeCount()app.setBadgeCount(n) / app.getBadgeCount()
process.platformplatform ("macos" not "darwin")
BrowserWindow.getAllWindows()core({cmd:"core_info"}) (추후 별도 API 예정)
preload.js미제공 — CEF 환경이라 Node API 노출 X
contextBridge미제공window.__suji__는 메인 월드 frozen bridge로 하드닝, 진짜 isolated-world는 roadmap

자세한 차이는 events.mdx 참조.