Zig 백엔드 SDK
This content is not available in your language yet.
@import("suji")로 접근. dylib으로 빌드되어 main suji 프로세스에 dlopen 됨.
App 빌더
섹션 제목: “App 빌더”const suji = @import("suji");const std = @import("std");
pub const my_app = suji.app() .named("my-plugin") // 선택 — ready/bye 로그 prefix 구분 .handle("ping", ping) // 1-arity .handle("save", save) // 2-arity (InvokeEvent) .on("window:all-closed", onAllClosed); // 이벤트 리스너
fn ping(req: suji.Request) suji.Response { return req.ok(.{ .msg = "pong" });}
fn save(req: suji.Request, event: suji.InvokeEvent) suji.Response { const content = req.string("content") orelse ""; std.debug.print("save from window {d}\n", .{event.window.id}); return req.ok(.{ .ok = true });}
fn onAllClosed(_: suji.Event) void { if (!std.mem.eql(u8, suji.platform(), suji.PLATFORM_MACOS)) { suji.quit(); }}
comptime { _ = suji.exportApp(my_app);}Request
섹션 제목: “Request”pub const Request = struct { raw: []const u8, // 원본 JSON arena: std.mem.Allocator, // 요청 스코프 arena
pub fn string(self, key: []const u8) ?[]const u8; pub fn int(self, key: []const u8) ?i64; pub fn float(self, key: []const u8) ?f64; pub fn bool(self, key: []const u8) ?bool; pub fn ok(self, value: anytype) Response; pub fn err(self, message: []const u8) Response;};Response
섹션 제목: “Response”pub const Response = struct { data: []const u8, // 직렬화된 JSON 바이트};req.ok(.{...}) / req.err(...)로만 생성. 직접 구성할 일 없음.
InvokeEvent
섹션 제목: “InvokeEvent”pub const InvokeEvent = struct { window: Window,
pub const Window = struct { id: u32, // wire `__window` 필드 — 호출한 창의 WM id name: ?[]const u8, // wire `__window_name` 필드 — 창 이름 (익명 창은 null) };};핸들러 시그니처 2가지 모두 허용:
fn h1(req: Request) Response { ... } // 기본fn h2(req: Request, event: InvokeEvent) Response { ... } // 창 식별 필요 시1-arity와 2-arity 모두 허용되며 호환성이 유지된다.
Event (Window listener용)
섹션 제목: “Event (Window listener용)”pub const Event = struct { channel: []const u8, data: []const u8,};on("window:all-closed", fn(Event) void) 같은 리스너 콜백이 받음.
InvokeEvent와 다른 역할 — 이벤트 구독용 payload.
유틸리티
섹션 제목: “유틸리티”suji.platform() []const u8; // "macos" | "linux" | "windows"suji.quit() void; // Electron app.quit() 대응suji.PLATFORM_MACOS, PLATFORM_LINUX, PLATFORM_WINDOWS // 상수크로스 호출
섹션 제목: “크로스 호출”fn callRust(req: suji.Request) suji.Response { var resp_buf: [1024]u8 = undefined; if (req.invoke("rust", "{\"cmd\":\"hash\",\"data\":\"abc\"}", &resp_buf)) |resp| { // resp는 다른 백엔드의 JSON 응답 return req.ok(.{ .from_rust = resp }); } return req.err("rust failed");}이벤트 발신
섹션 제목: “이벤트 발신”suji.send("theme-changed", "{\"color\":\"dark\"}");모든 창의 __suji__.on("theme-changed", ...) 리스너에 JSON 파싱되어 전달.
windows — 창 조작
섹션 제목: “windows — 창 조작”Frontend @suji/api의 windows.*와 같은 cmd JSON을 코어로 보낸다. 응답은 ?[]const u8 JSON 문자열.
// 새 창 (단축)_ = suji.windows.createSimple("Settings", "http://localhost:12300/settings");
// 옵션 풀 셋 — opts_json은 cmd 객체 안의 raw 필드 (camelCase)_ = suji.windows.create("\"name\":\"hud\",\"frame\":false,\"transparent\":true,\"alwaysOnTop\":true");
// 페이지 조작_ = suji.windows.loadURL(2, "https://example.com/");_ = suji.windows.reload(2, true); // ignoreCache_ = suji.windows.executeJavaScript(2, "document.title='Hi'"); // fire-and-forget_ = suji.windows.setTitle(2, "New Title");_ = suji.windows.setBounds(2, .{ .x = 100, .y = 100, .width = 1200, .height = 800 });
// 상태 조회_ = suji.windows.getURL(2); // {ok, url} 또는 {ok:false, url:null}_ = suji.windows.isLoading(2); // {ok, loading}
// 줌_ = suji.windows.setZoomLevel(2, 1.5); // logarithmic_ = suji.windows.setZoomFactor(2, 1.2); // linear (factor=pow(1.2, level))_ = suji.windows.getZoomLevel(2);_ = suji.windows.getZoomFactor(2);
// DevTools_ = suji.windows.openDevTools(2);_ = suji.windows.toggleDevTools(2);_ = suji.windows.isDevToolsOpened(2);
// 편집/검색_ = suji.windows.undo(2);_ = suji.windows.copy(2);_ = suji.windows.findInPage(2, "hello", .{ .forward = true, .match_case = false, .find_next = false });_ = suji.windows.stopFindInPage(2, /* clear_selection */ true);
// PDF 인쇄 (콜백 async — 결과는 `window:pdf-print-finished` 이벤트)_ = suji.windows.printToPDF(2, "/tmp/report.pdf");title/url/code/text 등 문자열 필드는 SDK가 자동 escape (" \\ 이스케이프 + control char drop).
fs — 파일 시스템
섹션 제목: “fs — 파일 시스템”응답은 ?[]const u8 JSON 문자열.
_ = suji.fs.mkdir("/tmp/suji", true);_ = suji.fs.writeFile("/tmp/suji/hello.txt", "hello\nworld");_ = suji.fs.readFile("/tmp/suji/hello.txt");_ = suji.fs.stat("/tmp/suji/hello.txt");_ = suji.fs.readdir("/tmp/suji");현재 텍스트 파일 중심 API이며 대용량/바이너리 스트리밍은 지원하지 않는다.