153 lines
5.8 KiB
EmacsLisp
153 lines
5.8 KiB
EmacsLisp
// el-platform — Platform abstraction surface for el-ui apps.
|
|
//
|
|
// The Rust crate defines `PlatformBackend` trait + per-target render backends
|
|
// (web/server/ios/android/macos/linux/windows). The El surface is narrower:
|
|
// El apps reach the host through the runtime's filesystem, network, and OS
|
|
// primitives. This vessel wraps those into a stable, named API so El callers
|
|
// don't depend directly on builtin names.
|
|
//
|
|
// RUNTIME PARITY GAPS:
|
|
// - There is no `PlatformBackend` polymorphism at the El layer. The runtime
|
|
// IS the backend; target selection happens during compilation/packaging,
|
|
// not at runtime.
|
|
// - DOM mutation, native widget mounting, event binding — none of those
|
|
// have El surfaces yet. Use el-ui-compiler when those land.
|
|
// - `fs_list` returns a JSON array string; consumers must parse with the
|
|
// forthcoming json_array_get builtin. Until that lands, callers should
|
|
// treat the value opaquely.
|
|
|
|
// ── Targets ─────────────────────────────────────────────────────────────────
|
|
|
|
fn target_web() -> String { "web" }
|
|
fn target_server() -> String { "server" }
|
|
fn target_ios() -> String { "ios" }
|
|
fn target_android() -> String { "android" }
|
|
fn target_macos() -> String { "macos" }
|
|
fn target_linux() -> String { "linux" }
|
|
fn target_windows() -> String { "windows" }
|
|
|
|
// The compiled binary's target is fixed at build time. EL_TARGET is set by
|
|
// the build harness; absent EL_TARGET, default to "server" (the El runtime
|
|
// runs as a host process).
|
|
fn platform_target() -> String {
|
|
let t: String = env("EL_TARGET")
|
|
if str_eq(t, "") { return "server" }
|
|
t
|
|
}
|
|
|
|
fn platform_is_native(t: String) -> Bool {
|
|
if str_eq(t, "ios") { return true }
|
|
if str_eq(t, "android") { return true }
|
|
if str_eq(t, "macos") { return true }
|
|
if str_eq(t, "linux") { return true }
|
|
if str_eq(t, "windows") { return true }
|
|
false
|
|
}
|
|
|
|
fn platform_supports_ssr(t: String) -> Bool {
|
|
str_eq(t, "server")
|
|
}
|
|
|
|
// ── Errors ──────────────────────────────────────────────────────────────────
|
|
|
|
fn err_io() -> String { "platform.io" }
|
|
fn err_network() -> String { "platform.network" }
|
|
fn err_unsupported() -> String { "platform.unsupported" }
|
|
fn err_env_missing() -> String { "platform.env_missing" }
|
|
|
|
// ── Environment ─────────────────────────────────────────────────────────────
|
|
|
|
fn platform_env(key: String) -> String {
|
|
env(key)
|
|
}
|
|
|
|
fn platform_env_or(key: String, fallback: String) -> String {
|
|
let v: String = env(key)
|
|
if str_eq(v, "") { return fallback }
|
|
v
|
|
}
|
|
|
|
// Strict variant: returns "" if missing, callers branch.
|
|
// (Runtime has no panic() — fail-soft return preserves type.)
|
|
fn platform_env_required(key: String) -> String {
|
|
let v: String = env(key)
|
|
if str_eq(v, "") {
|
|
println("[el-platform] ERROR " + err_env_missing() + ":" + key)
|
|
return ""
|
|
}
|
|
v
|
|
}
|
|
|
|
// ── Filesystem ──────────────────────────────────────────────────────────────
|
|
|
|
fn platform_fs_read(path: String) -> String {
|
|
fs_read(path)
|
|
}
|
|
|
|
fn platform_fs_write(path: String, content: String) -> Bool {
|
|
fs_write(path, content)
|
|
true
|
|
}
|
|
|
|
// Returns a JSON array of entry names (opaque until json_array_get lands).
|
|
fn platform_fs_list(path: String) -> String {
|
|
let raw: String = fs_list(path)
|
|
if str_eq(raw, "") { return "[]" }
|
|
raw
|
|
}
|
|
|
|
fn platform_fs_exists(path: String) -> Bool {
|
|
let raw: String = fs_read(path)
|
|
!str_eq(raw, "")
|
|
}
|
|
|
|
// ── HTTP ────────────────────────────────────────────────────────────────────
|
|
|
|
fn platform_http_get(url: String) -> String {
|
|
http_get(url)
|
|
}
|
|
|
|
fn platform_http_post(url: String, body: String) -> String {
|
|
http_post(url, body)
|
|
}
|
|
|
|
fn platform_http_post_json(url: String, json_body: String) -> String {
|
|
http_post_json(url, json_body)
|
|
}
|
|
|
|
fn platform_http_get_authed(url: String, bearer: String) -> String {
|
|
let headers: String = "Authorization: Bearer " + bearer
|
|
http_get_with_headers(url, headers)
|
|
}
|
|
|
|
fn platform_http_post_authed(url: String, body: String, bearer: String) -> String {
|
|
let headers: String = "Authorization: Bearer " + bearer
|
|
http_post_with_headers(url, body, headers)
|
|
}
|
|
|
|
// ── Time / OS clock ─────────────────────────────────────────────────────────
|
|
|
|
fn platform_now() -> Int {
|
|
time_now()
|
|
}
|
|
|
|
fn platform_sleep_ms(ms: Int) -> Bool {
|
|
sleep_ms(ms)
|
|
true
|
|
}
|
|
|
|
// ── Identity (for trace/log correlation) ───────────────────────────────────
|
|
|
|
fn platform_uuid() -> String {
|
|
uuid_v4()
|
|
}
|
|
|
|
// ── Entry — smoke test ──────────────────────────────────────────────────────
|
|
//
|
|
// elc-bug-workaround: top-level `let` does not scope into the surrounding
|
|
// statement substitution in the entry block, so we call platform_target()
|
|
// inline at each use site.
|
|
|
|
println("[el-platform] target=" + platform_target() + " ssr=" + bool_to_str(platform_supports_ssr(platform_target())))
|
|
println("[el-platform] uuid=" + platform_uuid())
|