Skip to main content

shape_ext_typescript/
lib.rs

1//! Shape TypeScript language runtime extension.
2//!
3//! Provides a `shape.language_runtime` capability that embeds V8 via deno_core
4//! for executing `foreign "typescript" { ... }` blocks in Shape programs.
5//!
6//! # ABI Exports
7//!
8//! - `shape_plugin_info()` -- plugin metadata
9//! - `shape_abi_version()` -- ABI version tag
10//! - `shape_capability_manifest()` -- declares LanguageRuntime capability
11//! - `shape_capability_vtable(contract, len)` -- generic vtable dispatch
12//! - `shape_language_runtime_vtable()` -- direct vtable accessor
13
14pub mod error_mapping;
15pub mod marshaling;
16pub mod runtime;
17
18use shape_abi_v1::{
19    ABI_VERSION, CAPABILITY_LANGUAGE_RUNTIME, CapabilityDescriptor, CapabilityKind,
20    CapabilityManifest, ErrorModel, LanguageRuntimeVTable, PluginInfo, PluginType,
21};
22use std::ffi::c_void;
23
24// ============================================================================
25// Plugin Metadata
26// ============================================================================
27
28#[unsafe(no_mangle)]
29pub extern "C" fn shape_plugin_info() -> *const PluginInfo {
30    static INFO: PluginInfo = PluginInfo {
31        name: c"typescript".as_ptr(),
32        version: c"0.1.0".as_ptr(),
33        plugin_type: PluginType::DataSource, // closest existing variant
34        description: c"TypeScript language runtime for foreign function blocks (V8 via deno_core)"
35            .as_ptr(),
36    };
37    &INFO
38}
39
40#[unsafe(no_mangle)]
41pub extern "C" fn shape_abi_version() -> u32 {
42    ABI_VERSION
43}
44
45// ============================================================================
46// Capability Manifest
47// ============================================================================
48
49#[unsafe(no_mangle)]
50pub extern "C" fn shape_capability_manifest() -> *const CapabilityManifest {
51    static CAPABILITIES: [CapabilityDescriptor; 1] = [CapabilityDescriptor {
52        kind: CapabilityKind::LanguageRuntime,
53        contract: c"shape.language_runtime".as_ptr(),
54        version: c"1".as_ptr(),
55        flags: 0,
56    }];
57    static MANIFEST: CapabilityManifest = CapabilityManifest {
58        capabilities: CAPABILITIES.as_ptr(),
59        capabilities_len: CAPABILITIES.len(),
60    };
61    &MANIFEST
62}
63
64// ============================================================================
65// VTable
66// ============================================================================
67
68#[unsafe(no_mangle)]
69pub extern "C" fn shape_language_runtime_vtable() -> *const LanguageRuntimeVTable {
70    static VTABLE: LanguageRuntimeVTable = LanguageRuntimeVTable {
71        init: Some(runtime::ts_init),
72        register_types: Some(runtime::ts_register_types),
73        compile: Some(runtime::ts_compile),
74        invoke: Some(runtime::ts_invoke),
75        dispose_function: Some(runtime::ts_dispose_function),
76        language_id: Some(runtime::ts_language_id),
77        get_lsp_config: Some(runtime::ts_get_lsp_config),
78        free_buffer: Some(runtime::ts_free_buffer),
79        drop: Some(runtime::ts_drop),
80        error_model: ErrorModel::Dynamic,
81    };
82    &VTABLE
83}
84
85#[unsafe(no_mangle)]
86pub extern "C" fn shape_capability_vtable(
87    contract: *const u8,
88    contract_len: usize,
89) -> *const c_void {
90    if contract.is_null() {
91        return std::ptr::null();
92    }
93    let contract = unsafe { std::slice::from_raw_parts(contract, contract_len) };
94    if contract == CAPABILITY_LANGUAGE_RUNTIME.as_bytes() {
95        shape_language_runtime_vtable() as *const c_void
96    } else {
97        std::ptr::null()
98    }
99}