Skip to content

feat(ffi): stateless C-ABI shared library for in-process embedding - #173

Open
lekt9 wants to merge 1 commit into
justrach:mainfrom
lekt9:ffi-embed-clean
Open

feat(ffi): stateless C-ABI shared library for in-process embedding#173
lekt9 wants to merge 1 commit into
justrach:mainfrom
lekt9:ffi-embed-clean

Conversation

@lekt9

@lekt9 lekt9 commented May 30, 2026

Copy link
Copy Markdown

Adds an optional zig build ffi target that emits libkuri_ffi (.dylib/.so/.dll), exposing a small stateless C ABI so a host can drive kuri's fetch/render path in-process — no HTTP server, no shared Bridge state, no subprocess.

API

char *kuri_fetch(const char *url, int mode);   // 0 = markdown, else raw HTML; NUL-terminated, caller frees
void  kuri_free(char *ptr);
int   kuri_ffi_abi_version(void);              // currently 1

How it works

src/ffi.zig reuses the same helpers kuri-fetch uses — validator.validateUrl (SSRF guard) → http_fetch.fetchHttpmarkdown.htmlToMarkdown. Pure Zig + spawned curl, so the lib links no quickjs and no curl-impersonate — just libc. It cross-compiles cleanly for every target with Zig's bundled libc (verified: aarch64/x86_64-macos, x86_64/aarch64-linux, x86_64-windows).

Why

Lets an embedding host (e.g. Bun bun:ffi dlopen) call kuri's fetch directly instead of running the long-lived server — handy for stateless one-shot fetches. Purely additive: one new build step + one new file; no existing target or behavior changes.

Verified

  • zig build ffilibkuri_ffi.dylib (native + cross targets).
  • Bun dlopenkuri_fetch("https://example.com", 0) → markdown rendered in-process.

Add src/ffi.zig + a `zig build ffi` target that emits libkuri_ffi (.dylib/.so),
exporting a stateless C-ABI fetch path:
  kuri_fetch(url, mode) -> NUL-terminated bytes (markdown|html), kuri_free, kuri_ffi_abi_version

No server, no Bridge, no shared state — reuses validator.validateUrl (SSRF guard)
+ http_fetch.fetchHttp + markdown.htmlToMarkdown. Pure-Zig deps + spawned curl;
needs no quickjs / curl-impersonate linkage. Lets a host (e.g. Bun bun:ffi
dlopen) drive kuri's fetch/render in-process instead of running the long-lived
kuri server.

Verified: built native (aarch64-macos, 4.9MB .dylib); Bun FFI dlopen → kuri_fetch
on https://example.com → markdown rendered in-process in ~2.5s.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant