diff --git a/el-compiler/runtime/el_runtime.js b/el-compiler/runtime/el_runtime.js index 88a16e1..a223fdb 100644 --- a/el-compiler/runtime/el_runtime.js +++ b/el-compiler/runtime/el_runtime.js @@ -766,6 +766,68 @@ function window_get(name) { return null; } +// ── Promise helpers ──────────────────────────────────────────────────────── +// +// Third-party APIs often return Promises but are not El @async functions. +// These helpers let El programs chain .then / .catch without needing +// native_js, and without requiring the callee to be @async. + +function promise_then(p, cb) { + return Promise.resolve(p).then(cb); +} + +function promise_catch(p, cb) { + return Promise.resolve(p).catch(cb); +} + +function promise_resolve(val) { + return Promise.resolve(val); +} + +function promise_reject(msg) { + return Promise.reject(new Error(String(msg))); +} + +// ── Object / Array utilities ─────────────────────────────────────────────── +// +// Structural operations on Any-typed JS values. These complement the +// El map/list primitives for interop with third-party library objects. + +function object_assign(target, source) { + return Object.assign(Object.assign({}, target), source); +} + +function object_keys(obj) { + if (obj === null || obj === undefined) return []; + return Object.keys(obj); +} + +function object_values(obj) { + if (obj === null || obj === undefined) return []; + return Object.values(obj); +} + +function json_deep_clone(obj) { + if (obj === null || obj === undefined) return null; + return JSON.parse(JSON.stringify(obj)); +} + +function array_from(iterable) { + if (iterable === null || iterable === undefined) return []; + return Array.from(iterable); +} + +function type_of(val) { + return typeof val; +} + +function instanceof_check(val, constructor_name) { + if (typeof globalThis[constructor_name] === 'function') { + return val instanceof globalThis[constructor_name]; + } + return false; +} + // ── native_js escape hatch ───────────────────────────────────────────────── // // Evaluate arbitrary JS from El source. Intended for calling third-party @@ -910,6 +972,11 @@ const __el = { console_log, // Window export helpers window_set, window_get, + // Promise helpers + promise_then, promise_catch, promise_resolve, promise_reject, + // Object / Array utilities + object_assign, object_keys, object_values, json_deep_clone, + array_from, type_of, instanceof_check, // native_js escape hatch native_js, native_js_call, // CGI / DHARMA / Engram / LLM (stubs) @@ -974,4 +1041,9 @@ export { console_log, // Window / native_js window_set, window_get, native_js, native_js_call, + // Promise helpers + promise_then, promise_catch, promise_resolve, promise_reject, + // Object / Array utilities + object_assign, object_keys, object_values, json_deep_clone, + array_from, type_of, instanceof_check, }; diff --git a/el-compiler/src/codegen-js.el b/el-compiler/src/codegen-js.el index 7717eaa..f0de87a 100644 --- a/el-compiler/src/codegen-js.el +++ b/el-compiler/src/codegen-js.el @@ -1105,6 +1105,9 @@ fn codegen_js_inner(stmts: [Map], source: String, bundle_mode: Bool js_emit_line(" window_location, window_redirect, window_on_load,") js_emit_line(" console_log,") js_emit_line(" window_set, window_get, native_js, native_js_call,") + js_emit_line(" promise_then, promise_catch, promise_resolve, promise_reject,") + js_emit_line(" object_assign, object_keys, object_values, json_deep_clone,") + js_emit_line(" array_from, type_of, instanceof_check,") js_emit_line("} = globalThis.__el;") js_emit_blank() }