From d28edcf04165504d5f707eca303fd1ce6fac2259 Mon Sep 17 00:00:00 2001 From: Hare Date: Thu, 13 Aug 2026 18:55:03 +0900 Subject: [PATCH] Share host-aware completion across runtimes --- Cargo.lock | 61 ++ crates/decodal-core/src/eval.rs | 36 + crates/decodal-core/src/lib.rs | 4 +- crates/decodal-core/src/module.rs | 36 +- .../src/completion.rs | 905 ++++++++++++++++++ crates/decodal-language-service/src/lib.rs | 16 + crates/decodal-lsp/src/lib.rs | 267 +++++- crates/decodal-wasm/Cargo.toml | 7 +- crates/decodal-wasm/src/host_value.rs | 228 +++++ crates/decodal-wasm/src/lib.rs | 289 +++--- crates/decodal-wasm/src/web_environment.rs | 209 ++++ packages/decodal-wasm/README.md | 45 +- packages/decodal-wasm/decodal_wasm.d.ts | 93 +- packages/decodal-wasm/decodal_wasm.js | 410 +++++++- packages/decodal-wasm/decodal_wasm_bg.wasm | Bin 361078 -> 514012 bytes .../decodal-wasm/decodal_wasm_bg.wasm.d.ts | 10 +- packages/decodal-wasm/mod.ts | 80 +- packages/decodal-wasm/package.json | 2 +- .../scripts/prepare-wasm-package.mjs | 112 ++- .../src/scripts/playground-completion.js | 286 +----- .../scripts/playground-completion.test.mjs | 133 ++- .../src/scripts/playground-environment.js | 67 ++ .../scripts/playground-environment.test.mjs | 37 + .../src/scripts/playground-runtime.test.mjs | 57 ++ site/decodal-site/src/scripts/playground.js | 24 +- 25 files changed, 2836 insertions(+), 578 deletions(-) create mode 100644 crates/decodal-language-service/src/completion.rs create mode 100644 crates/decodal-wasm/src/host_value.rs create mode 100644 crates/decodal-wasm/src/web_environment.rs create mode 100644 site/decodal-site/src/scripts/playground-environment.js create mode 100644 site/decodal-site/src/scripts/playground-environment.test.mjs create mode 100644 site/decodal-site/src/scripts/playground-runtime.test.mjs diff --git a/Cargo.lock b/Cargo.lock index 97d6350..00aeb18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,6 +114,9 @@ name = "decodal-wasm" version = "0.1.2" dependencies = [ "decodal", + "decodal-language-service", + "js-sys", + "serde-wasm-bindgen", "serde_json", "wasm-bindgen", ] @@ -133,12 +136,47 @@ dependencies = [ "bitflags", ] +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "js-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + [[package]] name = "log" version = "0.4.33" @@ -183,6 +221,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + [[package]] name = "proc-macro2" version = "1.0.106" @@ -246,6 +290,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -296,6 +351,12 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "syn" version = "2.0.117" diff --git a/crates/decodal-core/src/eval.rs b/crates/decodal-core/src/eval.rs index aadd4b1..ece0cc6 100644 --- a/crates/decodal-core/src/eval.rs +++ b/crates/decodal-core/src/eval.rs @@ -107,6 +107,42 @@ impl Engine { thunk } + /// Returns the values installed in the host-owned global environment. + /// + /// Language tooling uses this after [`crate::HostEnvironment`] configures a + /// fresh engine, so editor-visible globals cannot drift from evaluation. + pub fn global_values(&mut self) -> Result> { + let bindings = self.envs[self.prelude_env.0 as usize].bindings.clone(); + bindings + .into_iter() + .map(|binding| Ok((binding.name, self.force(binding.value)?))) + .collect() + } + + /// Returns the immediately visible fields of an object runtime value. + pub fn value_fields( + &mut self, + value: &RuntimeValue, + ) -> Result>> { + let object = match value { + RuntimeValue::Concrete(crate::runtime::ConcreteValue::Object(object)) => object, + RuntimeValue::Abstract(abstract_value) => { + let Some(default) = abstract_value.default else { + return Ok(None); + }; + let default = self.force(default)?; + return self.value_fields(&default); + } + _ => return Ok(None), + }; + let fields = object.fields.clone(); + fields + .into_iter() + .map(|field| Ok((field.name, self.force(field.value)?))) + .collect::>>() + .map(Some) + } + pub fn add_root_source( &mut self, key: impl Into, diff --git a/crates/decodal-core/src/lib.rs b/crates/decodal-core/src/lib.rs index 9d50786..e0dec7a 100644 --- a/crates/decodal-core/src/lib.rs +++ b/crates/decodal-core/src/lib.rs @@ -23,7 +23,9 @@ pub use diagnostic::{Diagnostic, DiagnosticKind, Result}; pub use embedding::{HostField, HostValue}; pub use environment::HostEnvironment; pub use eval::{Engine, format_diagnostic_with}; -pub use module::{EmptyLoader, ImportLoader, LoadedImport, LoadedSource, LoadedValue, Module}; +pub use module::{ + EmptyLoader, ImportCandidate, ImportLoader, LoadedImport, LoadedSource, LoadedValue, Module, +}; pub use parser::{ParseOutput, Parser, SourceForm, parse_source, parse_source_with_source_id}; pub use runtime::{Constraint, Data, ExprRef, LiteralValue, ModuleId, PrimitiveType, RuntimeValue}; pub use span::{SourceId, Span}; diff --git a/crates/decodal-core/src/module.rs b/crates/decodal-core/src/module.rs index 70b5f8d..bbda6a4 100644 --- a/crates/decodal-core/src/module.rs +++ b/crates/decodal-core/src/module.rs @@ -1,4 +1,4 @@ -use alloc::string::String; +use alloc::{string::String, vec::Vec}; use crate::{ Ast, ExprId, HostValue, SourceForm, SourceId, @@ -36,6 +36,27 @@ pub enum LoadedImport { Value(LoadedValue), } +/// An import specifier offered by host-owned language tooling. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ImportCandidate { + pub specifier: String, + pub detail: Option, +} + +impl ImportCandidate { + pub fn new(specifier: impl Into) -> Self { + Self { + specifier: specifier.into(), + detail: None, + } + } + + pub fn with_detail(mut self, detail: impl Into) -> Self { + self.detail = Some(detail.into()); + self + } +} + impl LoadedImport { pub fn source( key: impl Into, @@ -59,6 +80,19 @@ impl LoadedImport { pub trait ImportLoader { fn load(&mut self, current_key: Option<&str>, specifier: &str) -> crate::Result; + + /// Returns host-resolvable import specifiers matching an unfinished prefix. + /// + /// Runtime-only loaders may keep the default implementation. Hosts that + /// provide an editor should implement this from the same namespace used by + /// [`ImportLoader::load`]. + fn complete_import( + &mut self, + _current_key: Option<&str>, + _prefix: &str, + ) -> crate::Result> { + Ok(Vec::new()) + } } #[derive(Debug, Clone, Copy, Default)] diff --git a/crates/decodal-language-service/src/completion.rs b/crates/decodal-language-service/src/completion.rs new file mode 100644 index 0000000..188e490 --- /dev/null +++ b/crates/decodal-language-service/src/completion.rs @@ -0,0 +1,905 @@ +use std::collections::{BTreeMap, HashMap}; + +use decodal::{ + Engine, HostEnvironment, HostValue, ImportLoader, LoadedImport, Result, RuntimeValue, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CompletionKind { + Keyword, + Constant, + Type, + Variable, + Namespace, + Property, + File, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CompletionItem { + pub label: String, + pub kind: CompletionKind, + pub detail: Option, + pub priority: i32, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CompletionResult { + /// UTF-8 byte offset at which the unfinished token starts. + pub from: usize, + pub items: Vec, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +struct FieldTree(BTreeMap); + +impl FieldTree { + fn new() -> Self { + Self::default() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + + fn insert(&mut self, name: String, fields: FieldTree) { + self.0.insert(name, fields); + } + + fn get(&self, name: &str) -> Option<&FieldTree> { + self.0.get(name) + } + + fn remove(&mut self, name: &str) -> Option { + self.0.remove(name) + } +} + +impl IntoIterator for FieldTree { + type Item = (String, FieldTree); + type IntoIter = std::collections::btree_map::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl FromIterator<(String, FieldTree)> for FieldTree { + fn from_iter>(iter: T) -> Self { + Self(iter.into_iter().collect()) + } +} + +pub(crate) fn complete( + environment: &E, + key: &str, + source: &str, + position: usize, + explicit: bool, +) -> Result> { + let position = floor_char_boundary(source, position.min(source.len())); + if let Some((from, prefix)) = unfinished_import(source, position) { + let mut loader = environment.create_loader(); + let items = loader + .complete_import(Some(key), prefix)? + .into_iter() + .map(|candidate| CompletionItem { + label: candidate.specifier, + kind: CompletionKind::File, + detail: candidate.detail, + priority: 30, + }) + .collect(); + return Ok(Some(CompletionResult { + from, + items: unique_items(items), + })); + } + + if in_string_or_comment(source, position) { + return Ok(None); + } + + let tokens = tokenize(source); + let local_fields = collect_fields(&tokens); + let imports = collect_import_bindings(&tokens); + let globals = collect_globals(environment)?; + + if let Some((from, path)) = member_path(source, position) { + let mut parts = path.split('.'); + let Some(root) = parts.next() else { + return Ok(None); + }; + let mut fields; + let detail; + if let Some(specifier) = imports.get(root) { + let mut loader = environment.create_loader(); + let loaded = loader.load(Some(key), specifier)?; + detail = match &loaded { + LoadedImport::Source(source) => source.name.clone(), + LoadedImport::Value(value) => value.key.clone(), + }; + fields = match loaded { + LoadedImport::Source(source) => collect_fields(&tokenize(&source.source)), + LoadedImport::Value(value) => fields_from_host_value(&value.value), + }; + } else if let Some(local) = local_fields.get(root) { + fields = local.clone(); + detail = String::from("local value"); + } else if let Some(global) = globals.get(root) { + fields = global.clone(); + detail = String::from("host global"); + } else { + return Ok(None); + } + + for part in parts { + let Some(nested) = fields.remove(part) else { + return Ok(None); + }; + fields = nested; + } + let items = fields + .into_iter() + .map(|(label, children)| CompletionItem { + label, + kind: if children.is_empty() { + CompletionKind::Property + } else { + CompletionKind::Namespace + }, + detail: Some(detail.clone()), + priority: 30, + }) + .collect(); + return Ok(Some(CompletionResult { + from, + items: unique_items(items), + })); + } + + let word_from = word_start(source, position); + if word_from == position && !explicit { + return Ok(None); + } + + let mut items = builtin_items(); + for (label, children) in local_fields { + items.push(CompletionItem { + label, + kind: if children.is_empty() { + CompletionKind::Variable + } else { + CompletionKind::Namespace + }, + detail: Some(if children.is_empty() { + String::from("local value") + } else { + String::from("local object") + }), + priority: 20, + }); + } + for label in collect_parameters(&tokens) { + items.push(CompletionItem { + label, + kind: CompletionKind::Variable, + detail: Some(String::from("parameter")), + priority: 20, + }); + } + for (label, specifier) in imports { + items.push(CompletionItem { + label, + kind: CompletionKind::Namespace, + detail: Some(specifier), + priority: 30, + }); + } + for (label, children) in globals { + items.push(CompletionItem { + label, + kind: if children.is_empty() { + CompletionKind::Variable + } else { + CompletionKind::Namespace + }, + detail: Some(String::from("host global")), + priority: 40, + }); + } + + Ok(Some(CompletionResult { + from: word_from, + items: unique_items(items), + })) +} + +fn builtin_items() -> Vec { + [ + ("let", CompletionKind::Keyword, "local bindings", 5), + ("in", CompletionKind::Keyword, "let body", 0), + ("match", CompletionKind::Keyword, "pattern matching", 5), + ("import", CompletionKind::Keyword, "load a module", 5), + ("default", CompletionKind::Keyword, "fallback value", 0), + ("true", CompletionKind::Constant, "Bool", 0), + ("false", CompletionKind::Constant, "Bool", 0), + ("String", CompletionKind::Type, "string constraint", 5), + ("Int", CompletionKind::Type, "integer constraint", 5), + ("Float", CompletionKind::Type, "float constraint", 5), + ("Bool", CompletionKind::Type, "boolean constraint", 5), + ] + .into_iter() + .map(|(label, kind, detail, priority)| CompletionItem { + label: label.into(), + kind, + detail: Some(detail.into()), + priority, + }) + .collect() +} + +fn collect_globals(environment: &E) -> Result { + let mut engine = environment.create_engine()?; + let mut fields = FieldTree::new(); + for (name, value) in engine.global_values()? { + fields.insert(name, fields_from_runtime(&mut engine, &value, 0)?); + } + Ok(fields) +} + +fn fields_from_runtime( + engine: &mut Engine, + value: &RuntimeValue, + depth: usize, +) -> Result { + if depth >= 32 { + return Ok(FieldTree::new()); + } + let Some(fields) = engine.value_fields(value)? else { + return Ok(FieldTree::new()); + }; + let mut tree = FieldTree::new(); + for (name, value) in fields { + tree.insert(name, fields_from_runtime(engine, &value, depth + 1)?); + } + Ok(tree) +} + +fn fields_from_host_value(value: &HostValue) -> FieldTree { + match value { + HostValue::Object(fields) => fields + .iter() + .map(|field| (field.name.clone(), fields_from_host_value(&field.value))) + .collect(), + HostValue::ArrayConstraint { + default: Some(value), + .. + } + | HostValue::Abstract { + default: Some(value), + .. + } => fields_from_host_value(value), + _ => FieldTree::new(), + } +} + +fn unique_items(items: Vec) -> Vec { + let mut unique = HashMap::::new(); + let mut order = Vec::new(); + for item in items { + if !unique.contains_key(&item.label) { + order.push(item.label.clone()); + } + let replace = unique + .get(&item.label) + .is_none_or(|previous| item.priority > previous.priority); + if replace { + unique.insert(item.label.clone(), item); + } + } + order + .into_iter() + .filter_map(|label| unique.remove(&label)) + .collect() +} + +#[derive(Debug, Clone, PartialEq, Eq)] +enum TokenKind { + Identifier(String), + String(String), + Symbol(char), + Arrow, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +struct Token { + kind: TokenKind, +} + +fn tokenize(source: &str) -> Vec { + let bytes = source.as_bytes(); + let mut tokens = Vec::new(); + let mut index = 0; + while index < bytes.len() { + match bytes[index] { + b' ' | b'\t' | b'\r' | b'\n' => index += 1, + b'#' => { + while index < bytes.len() && bytes[index] != b'\n' { + index += 1; + } + } + b'"' => { + index += 1; + let start = index; + let mut escaped = false; + while index < bytes.len() { + let byte = bytes[index]; + if escaped { + escaped = false; + } else if byte == b'\\' { + escaped = true; + } else if byte == b'"' || byte == b'\n' { + break; + } + index += 1; + } + let value = unescape_string(&source[start..index]); + index = index.saturating_add(1); + tokens.push(Token { + kind: TokenKind::String(value), + }); + } + byte if is_identifier_start(byte) => { + let start = index; + index += 1; + while index < bytes.len() && is_identifier_continue(bytes[index]) { + index += 1; + } + tokens.push(Token { + kind: TokenKind::Identifier(source[start..index].into()), + }); + } + b'=' if bytes.get(index + 1) == Some(&b'>') => { + tokens.push(Token { + kind: TokenKind::Arrow, + }); + index += 2; + } + byte => { + tokens.push(Token { + kind: TokenKind::Symbol(byte as char), + }); + index += 1; + } + } + } + tokens +} + +fn unescape_string(value: &str) -> String { + let mut chars = value.chars(); + let mut unescaped = String::new(); + while let Some(ch) = chars.next() { + if ch != '\\' { + unescaped.push(ch); + continue; + } + let Some(escaped) = chars.next() else { + unescaped.push('\\'); + break; + }; + unescaped.push(match escaped { + 'n' => '\n', + 'r' => '\r', + 't' => '\t', + escaped => escaped, + }); + } + unescaped +} + +fn collect_fields(tokens: &[Token]) -> FieldTree { + let mut fields = FieldTree::new(); + collect_fields_in(tokens, 0, tokens.len(), &mut fields); + fields +} + +fn collect_fields_in(tokens: &[Token], start: usize, end: usize, fields: &mut FieldTree) { + let mut index = start; + while index < end { + let Some((path, equals)) = field_definition_at(tokens, index, end) else { + index += 1; + continue; + }; + let value_start = equals + 1; + let value_end = definition_end(tokens, value_start, end); + let mut nested = &mut *fields; + for part in path { + nested = nested.0.entry(part).or_default(); + } + collect_fields_in(tokens, value_start, value_end, nested); + index = value_end.saturating_add(1); + } +} + +fn field_definition_at(tokens: &[Token], start: usize, end: usize) -> Option<(Vec, usize)> { + let TokenKind::Identifier(first) = &tokens.get(start)?.kind else { + return None; + }; + let mut path = vec![first.clone()]; + let mut index = start + 1; + while index + 1 < end + && matches!(tokens[index].kind, TokenKind::Symbol('.')) + && matches!(tokens[index + 1].kind, TokenKind::Identifier(_)) + { + let TokenKind::Identifier(part) = &tokens[index + 1].kind else { + unreachable!() + }; + path.push(part.clone()); + index += 2; + } + matches!( + tokens.get(index).map(|token| &token.kind), + Some(TokenKind::Symbol('=')) + ) + .then_some((path, index)) +} + +fn definition_end(tokens: &[Token], start: usize, end: usize) -> usize { + let mut delimiters = Vec::new(); + for (index, token) in tokens.iter().enumerate().take(end).skip(start) { + match token.kind { + TokenKind::Symbol('(' | '[' | '{') => delimiters.push(token.kind.clone()), + TokenKind::Symbol(')') if matches!(delimiters.last(), Some(TokenKind::Symbol('('))) => { + delimiters.pop(); + } + TokenKind::Symbol(']') if matches!(delimiters.last(), Some(TokenKind::Symbol('['))) => { + delimiters.pop(); + } + TokenKind::Symbol('}') if matches!(delimiters.last(), Some(TokenKind::Symbol('{'))) => { + delimiters.pop(); + } + TokenKind::Symbol(';') if delimiters.is_empty() => return index, + _ => {} + } + } + end +} + +fn collect_import_bindings(tokens: &[Token]) -> BTreeMap { + let mut imports = BTreeMap::new(); + for window in tokens.windows(4) { + let ( + TokenKind::Identifier(binding), + TokenKind::Symbol('='), + TokenKind::Identifier(keyword), + TokenKind::String(specifier), + ) = ( + &window[0].kind, + &window[1].kind, + &window[2].kind, + &window[3].kind, + ) + else { + continue; + }; + if keyword == "import" { + imports.insert(binding.clone(), specifier.clone()); + } + } + imports +} + +fn collect_parameters(tokens: &[Token]) -> Vec { + let mut parameters = Vec::new(); + for (close, token) in tokens.iter().enumerate() { + if !matches!(token.kind, TokenKind::Symbol(')')) + || !matches!( + tokens.get(close + 1).map(|token| &token.kind), + Some(TokenKind::Arrow) + ) + { + continue; + } + let Some(open) = matching_open_paren(tokens, close) else { + continue; + }; + let mut depth = 0usize; + let mut segment_start = true; + for token in &tokens[open + 1..close] { + match &token.kind { + TokenKind::Symbol('(' | '[' | '{') => depth += 1, + TokenKind::Symbol(')' | ']' | '}') => depth = depth.saturating_sub(1), + TokenKind::Symbol(',') if depth == 0 => segment_start = true, + TokenKind::Identifier(name) if depth == 0 && segment_start => { + parameters.push(name.clone()); + segment_start = false; + } + _ => {} + } + } + } + parameters +} + +fn matching_open_paren(tokens: &[Token], close: usize) -> Option { + let mut depth = 0usize; + for index in (0..close).rev() { + match tokens[index].kind { + TokenKind::Symbol(')') => depth += 1, + TokenKind::Symbol('(') if depth == 0 => return Some(index), + TokenKind::Symbol('(') => depth -= 1, + _ => {} + } + } + None +} + +fn unfinished_import(source: &str, position: usize) -> Option<(usize, &str)> { + let bytes = source.as_bytes(); + let mut index = 0usize; + let mut previous_word = None; + while index < position { + match bytes[index] { + b' ' | b'\t' | b'\r' | b'\n' => index += 1, + b'#' => { + while index < position && bytes[index] != b'\n' { + index += 1; + } + previous_word = None; + } + b'"' => { + let from = index + 1; + index += 1; + let mut escaped = false; + while index < position { + let byte = bytes[index]; + if escaped { + escaped = false; + } else if byte == b'\\' { + escaped = true; + } else if byte == b'"' || byte == b'\n' { + break; + } + index += 1; + } + if index == position && previous_word == Some("import") { + return Some((from, &source[from..position])); + } + index = index.saturating_add(1); + previous_word = None; + } + byte if is_identifier_start(byte) => { + let start = index; + index += 1; + while index < position && is_identifier_continue(bytes[index]) { + index += 1; + } + previous_word = Some(&source[start..index]); + } + _ => { + index += 1; + previous_word = None; + } + } + } + None +} + +fn in_string_or_comment(source: &str, position: usize) -> bool { + let bytes = source.as_bytes(); + let mut index = 0usize; + while index < position { + match bytes[index] { + b'#' => { + while index < position && bytes[index] != b'\n' { + index += 1; + } + if index == position { + return true; + } + } + b'"' => { + index += 1; + let mut escaped = false; + while index < position { + let byte = bytes[index]; + if escaped { + escaped = false; + } else if byte == b'\\' { + escaped = true; + } else if byte == b'"' || byte == b'\n' { + break; + } + index += 1; + } + if index == position { + return true; + } + index = index.saturating_add(1); + } + _ => index += 1, + } + } + false +} + +fn member_path(source: &str, position: usize) -> Option<(usize, &str)> { + let bytes = source.as_bytes(); + let from = word_start(source, position); + if from == 0 || bytes[from - 1] != b'.' { + return None; + } + let mut base_start = from - 1; + while base_start > 0 { + let byte = bytes[base_start - 1]; + if is_identifier_continue(byte) || byte == b'.' { + base_start -= 1; + } else { + break; + } + } + let base = &source[base_start..from - 1]; + (!base.is_empty() + && base + .split('.') + .all(|part| !part.is_empty() && is_identifier(part))) + .then_some((from, base)) +} + +fn word_start(source: &str, position: usize) -> usize { + let bytes = source.as_bytes(); + let mut from = position; + while from > 0 && is_identifier_continue(bytes[from - 1]) { + from -= 1; + } + from +} + +fn is_identifier(value: &str) -> bool { + let bytes = value.as_bytes(); + bytes.first().is_some_and(|byte| is_identifier_start(*byte)) + && bytes[1..].iter().all(|byte| is_identifier_continue(*byte)) +} + +fn is_identifier_start(byte: u8) -> bool { + byte.is_ascii_alphabetic() || byte == b'_' +} + +fn is_identifier_continue(byte: u8) -> bool { + is_identifier_start(byte) || byte.is_ascii_digit() +} + +fn floor_char_boundary(source: &str, mut position: usize) -> usize { + while !source.is_char_boundary(position) { + position -= 1; + } + position +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use decodal::{ + Diagnostic, DiagnosticKind, EmptyLoader, HostValue, ImportCandidate, LoadedImport, Span, + }; + + use super::*; + + #[derive(Clone, Default)] + struct TestEnvironment { + files: BTreeMap, + } + + #[derive(Clone, Default)] + struct TestLoader { + files: BTreeMap, + } + + impl ImportLoader for TestLoader { + fn load(&mut self, _current_key: Option<&str>, specifier: &str) -> Result { + if specifier == "./post.md" { + return Ok(LoadedImport::value( + "post.md", + HostValue::object([ + ( + "frontmatter", + HostValue::object([ + ("title", HostValue::string("Hello")), + ("draft", HostValue::bool(false)), + ]), + ), + ("body", HostValue::string("# Hello")), + ]), + )); + } + let key = resolve_virtual("main.dcdl", specifier); + let Some(source) = self.files.get(&key) else { + return Err(Diagnostic::new( + DiagnosticKind::Import, + Span::default(), + "unknown import", + )); + }; + Ok(LoadedImport::source(key.clone(), key, source)) + } + + fn complete_import( + &mut self, + _current_key: Option<&str>, + prefix: &str, + ) -> Result> { + Ok(self + .files + .keys() + .map(|path| format!("./{path}")) + .filter(|path| path.starts_with(prefix)) + .map(ImportCandidate::new) + .collect()) + } + } + + impl HostEnvironment for TestEnvironment { + type Loader = TestLoader; + + fn create_loader(&self) -> Self::Loader { + TestLoader { + files: self.files.clone(), + } + } + + fn configure_engine(&self, engine: &mut Engine) -> Result<()> { + engine.bind_global( + "App", + HostValue::object([( + "config", + HostValue::object([ + ("enabled", HostValue::bool_type()), + ("port", HostValue::int_type()), + ]), + )]), + )?; + Ok(()) + } + } + + fn environment() -> TestEnvironment { + TestEnvironment { + files: BTreeMap::from([ + ( + "schemas/service.dcdl".into(), + "Service = { name = String; resources = { cpu = Int; }; };".into(), + ), + ( + "env/production.dcdl".into(), + "capacity = { cpu = 2000; };".into(), + ), + ( + "資料/service.dcdl".into(), + "Service = { label = String; };".into(), + ), + ]), + } + } + + fn labels(result: CompletionResult) -> Vec { + result.items.into_iter().map(|item| item.label).collect() + } + + #[test] + fn completes_import_paths_from_the_host_loader() { + let source = "schema = import \"./sch"; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(result.from, source.len() - 5); + assert!(labels(result).contains(&"./schemas/service.dcdl".into())); + } + + #[test] + fn completes_nested_fields_from_imported_source() { + let source = "let schema = import \"./schemas/service.dcdl\"; in schema.Service."; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(labels(result), ["name", "resources"]); + } + + #[test] + fn completes_structured_host_imports() { + let source = "let post = import \"./post.md\"; in post.frontmatter."; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(labels(result), ["draft", "title"]); + } + + #[test] + fn preserves_unicode_import_specifiers() { + let source = "let schema = import \"./資料/service.dcdl\"; in schema.Service."; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(labels(result), ["label"]); + } + + #[test] + fn completes_host_globals_from_the_evaluation_environment() { + let source = "App.config."; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(labels(result), ["enabled", "port"]); + } + + #[test] + fn completes_language_locals_parameters_and_partial_members() { + let source = "let service = { port = 8080; }; in (value: Int) => service.po"; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + assert_eq!(result.from, source.len() - 2); + assert_eq!(labels(result), ["port"]); + + let source = "let service = { port = 8080; }; in (value: Int) => val"; + let result = complete(&environment(), "main.dcdl", source, source.len(), false) + .unwrap() + .unwrap(); + let labels = labels(result); + assert!(labels.contains(&"String".into())); + assert!(labels.contains(&"service".into())); + assert!(labels.contains(&"value".into())); + assert!(labels.contains(&"App".into())); + } + + #[test] + fn suppresses_completions_in_strings_and_comments() { + let string = "value = \"hello world\""; + assert!( + complete(&environment(), "main.dcdl", string, string.len() - 1, false) + .unwrap() + .is_none() + ); + let comment = "value = true; # hello"; + assert!( + complete(&environment(), "main.dcdl", comment, comment.len(), false) + .unwrap() + .is_none() + ); + } + + #[test] + fn empty_environment_remains_supported() { + let result = complete(&EmptyEnvironment, "main.dcdl", "Str", 3, false) + .unwrap() + .unwrap(); + assert!(labels(result).contains(&"String".into())); + } + + struct EmptyEnvironment; + + impl HostEnvironment for EmptyEnvironment { + type Loader = EmptyLoader; + + fn create_loader(&self) -> Self::Loader { + EmptyLoader + } + } + + fn resolve_virtual(current: &str, specifier: &str) -> String { + let mut parts = current.split('/').collect::>(); + parts.pop(); + for part in specifier.split('/') { + match part { + "" | "." => {} + ".." => { + parts.pop(); + } + part => parts.push(part), + } + } + parts.join("/") + } +} diff --git a/crates/decodal-language-service/src/lib.rs b/crates/decodal-language-service/src/lib.rs index 82c1827..7f21daf 100644 --- a/crates/decodal-language-service/src/lib.rs +++ b/crates/decodal-language-service/src/lib.rs @@ -1,5 +1,9 @@ use decodal::{Data, Diagnostic, HostEnvironment, Result}; +mod completion; + +pub use completion::{CompletionItem, CompletionKind, CompletionResult}; + /// Semantic tooling backed by the same host environment as production. pub struct LanguageService { environment: E, @@ -59,6 +63,18 @@ impl LanguageService { }, } } + + /// Completes the document using the same host globals and import loader as + /// production evaluation. + pub fn complete( + &self, + key: impl AsRef, + source: &str, + position: usize, + explicit: bool, + ) -> Result> { + completion::complete(&self.environment, key.as_ref(), source, position, explicit) + } } #[derive(Debug, Clone, PartialEq)] diff --git a/crates/decodal-lsp/src/lib.rs b/crates/decodal-lsp/src/lib.rs index f2ea29a..c7405a8 100644 --- a/crates/decodal-lsp/src/lib.rs +++ b/crates/decodal-lsp/src/lib.rs @@ -6,19 +6,23 @@ use std::{ }; use decodal::{ - Diagnostic as DecodalDiagnostic, DiagnosticKind, HostEnvironment, ImportLoader, LoadedImport, - LoadedSource, SourceId, Span, + Diagnostic as DecodalDiagnostic, DiagnosticKind, HostEnvironment, ImportCandidate, + ImportLoader, LoadedImport, LoadedSource, SourceId, Span, +}; +use decodal_language_service::{ + CompletionKind as ServiceCompletionKind, CompletionResult, LanguageService, SemanticAnalysis, }; -use decodal_language_service::{LanguageService, SemanticAnalysis}; use decodal_language_tools::format_source; use lsp_server::{Connection, ErrorCode, Message, Notification, Request, Response}; pub use lsp_types::InitializeParams; use lsp_types::{ - Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DidChangeTextDocumentParams, - DidCloseTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, - DocumentFormattingParams, InitializeResult, Location, NumberOrString, OneOf, Position, - PositionEncodingKind, PublishDiagnosticsParams, Range, SaveOptions, ServerCapabilities, - ServerInfo, TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, + CompletionItem, CompletionItemKind, CompletionOptions, CompletionParams, CompletionResponse, + CompletionTextEdit, CompletionTriggerKind, Diagnostic, DiagnosticRelatedInformation, + DiagnosticSeverity, DidChangeTextDocumentParams, DidCloseTextDocumentParams, + DidOpenTextDocumentParams, DidSaveTextDocumentParams, DocumentFormattingParams, + InitializeResult, Location, NumberOrString, OneOf, Position, PositionEncodingKind, + PublishDiagnosticsParams, Range, SaveOptions, ServerCapabilities, ServerInfo, + TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, TextDocumentSyncSaveOptions, TextEdit, Uri, }; @@ -124,6 +128,11 @@ fn server_capabilities() -> ServerCapabilities { }, )), document_formatting_provider: Some(OneOf::Left(true)), + completion_provider: Some(CompletionOptions { + resolve_provider: Some(false), + trigger_characters: Some(vec![String::from("."), String::from("/")]), + ..CompletionOptions::default() + }), ..ServerCapabilities::default() } } @@ -166,11 +175,66 @@ impl Server { fn handle_request(&self, request: Request) -> ServerResult { match request.method.as_str() { + "textDocument/completion" => self.complete_document(request), "textDocument/formatting" => self.format_document(request), _ => self.reject_unknown_request(request), } } + fn complete_document(&self, request: Request) -> ServerResult { + let id = request.id; + let params: CompletionParams = match serde_json::from_value(request.params) { + Ok(params) => params, + Err(error) => { + self.connection + .sender + .send(Message::Response(Response::new_err( + id, + ErrorCode::InvalidParams as i32, + error.to_string(), + )))?; + return Ok(()); + } + }; + let document_id = params.text_document_position.text_document.uri.as_str(); + let Some(document) = self.documents.get(document_id) else { + self.connection + .sender + .send(Message::Response(Response::new_ok( + id, + Option::::None, + )))?; + return Ok(()); + }; + let position = params.text_document_position.position; + let offset = position_to_byte_offset(&document.source, position); + let explicit = params + .context + .is_some_and(|context| context.trigger_kind == CompletionTriggerKind::INVOKED); + let completion = + match self + .service + .complete(&document.key, &document.source, offset, explicit) + { + Ok(completion) => completion + .map(|completion| completion_to_lsp(completion, &document.source, offset)), + Err(error) => { + self.connection + .sender + .send(Message::Response(Response::new_err( + id, + ErrorCode::InternalError as i32, + error.message, + )))?; + return Ok(()); + } + }; + self.connection + .sender + .send(Message::Response(Response::new_ok(id, completion)))?; + Ok(()) + } + fn format_document(&self, request: Request) -> ServerResult { let id = request.id; let params: DocumentFormattingParams = match serde_json::from_value(request.params) { @@ -413,6 +477,42 @@ fn span_to_range(source: &str, span: Span) -> Range { } } +fn completion_to_lsp( + completion: CompletionResult, + source: &str, + offset: usize, +) -> CompletionResponse { + let range = Range::new( + byte_offset_to_position(source, completion.from), + byte_offset_to_position(source, offset), + ); + CompletionResponse::Array( + completion + .items + .into_iter() + .map(|item| CompletionItem { + sort_text: Some(format!("{:04}-{}", 9999 - item.priority, item.label)), + text_edit: Some(CompletionTextEdit::Edit(TextEdit::new( + range, + item.label.clone(), + ))), + label: item.label, + kind: Some(match item.kind { + ServiceCompletionKind::Keyword => CompletionItemKind::KEYWORD, + ServiceCompletionKind::Constant => CompletionItemKind::CONSTANT, + ServiceCompletionKind::Type => CompletionItemKind::TYPE_PARAMETER, + ServiceCompletionKind::Variable => CompletionItemKind::VARIABLE, + ServiceCompletionKind::Namespace => CompletionItemKind::MODULE, + ServiceCompletionKind::Property => CompletionItemKind::PROPERTY, + ServiceCompletionKind::File => CompletionItemKind::FILE, + }), + detail: item.detail, + ..CompletionItem::default() + }) + .collect(), + ) +} + fn byte_offset_to_position(source: &str, offset: usize) -> Position { let mut offset = offset.min(source.len()); while !source.is_char_boundary(offset) { @@ -431,6 +531,36 @@ fn byte_offset_to_position(source: &str, offset: usize) -> Position { Position { line, character } } +fn position_to_byte_offset(source: &str, position: Position) -> usize { + let mut line = 0u32; + let mut line_start = 0usize; + for (offset, ch) in source.char_indices() { + if line == position.line { + line_start = offset; + break; + } + if ch == '\n' { + line += 1; + line_start = offset + ch.len_utf8(); + } + } + if line < position.line { + return source.len(); + } + let mut utf16 = 0u32; + for (relative, ch) in source[line_start..].char_indices() { + if ch == '\n' || utf16 >= position.character { + return line_start + relative; + } + let next = utf16 + ch.len_utf16() as u32; + if next > position.character { + return line_start + relative; + } + utf16 = next; + } + source.len() +} + fn document_key(uri: &Uri) -> String { if uri .scheme() @@ -543,6 +673,64 @@ impl ImportLoader for FileSystemLoader { source, })) } + + fn complete_import( + &mut self, + current_key: Option<&str>, + prefix: &str, + ) -> decodal::Result> { + let current_dir = current_key + .and_then(|key| Path::new(key).parent()) + .unwrap_or_else(|| Path::new(".")); + let prefix_path = Path::new(prefix); + let resolved = if prefix_path.is_absolute() { + prefix_path.to_path_buf() + } else { + current_dir.join(prefix_path) + }; + let ends_with_separator = prefix.ends_with('/') || prefix.ends_with('\\'); + let directory = if ends_with_separator { + resolved.as_path() + } else { + resolved.parent().unwrap_or_else(|| Path::new(".")) + }; + let fragment = if ends_with_separator { + "" + } else { + resolved + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or("") + }; + let label_base = if ends_with_separator { + prefix.to_owned() + } else { + prefix + .rfind(['/', '\\']) + .map_or_else(String::new, |index| prefix[..=index].to_owned()) + }; + let Ok(entries) = fs::read_dir(directory) else { + return Ok(Vec::new()); + }; + let mut candidates = Vec::new(); + for entry in entries.flatten() { + let name = entry.file_name().to_string_lossy().into_owned(); + if !name.starts_with(fragment) { + continue; + } + let is_directory = entry.file_type().is_ok_and(|kind| kind.is_dir()); + let mut specifier = format!("{label_base}{name}"); + if is_directory { + specifier.push('/'); + } + candidates.push( + ImportCandidate::new(specifier) + .with_detail(entry.path().to_string_lossy().into_owned()), + ); + } + candidates.sort_by(|left, right| left.specifier.cmp(&right.specifier)); + Ok(candidates) + } } #[cfg(test)] @@ -642,6 +830,14 @@ mod tests { byte_offset_to_position(source, source.len()), Position::new(1, 1) ); + assert_eq!(position_to_byte_offset(source, Position::new(0, 0)), 0); + assert_eq!(position_to_byte_offset(source, Position::new(0, 1)), 1); + assert_eq!(position_to_byte_offset(source, Position::new(0, 3)), 5); + assert_eq!(position_to_byte_offset(source, Position::new(1, 0)), 6); + assert_eq!( + position_to_byte_offset(source, Position::new(1, 1)), + source.len() + ); } #[test] @@ -651,7 +847,7 @@ mod tests { } #[test] - fn publishes_host_environment_diagnostics_over_lsp() { + fn serves_host_environment_diagnostics_and_completion_over_lsp() { let (server_connection, client_connection) = Connection::memory(); let initialized_workspace = Arc::new(Mutex::new(None)); let server_workspace = Arc::clone(&initialized_workspace); @@ -689,6 +885,9 @@ mod tests { panic!("expected initialize response") }; assert!(initialized.response_result.is_ok()); + let initialize_result: InitializeResult = + serde_json::from_value(initialized.response_result.as_ref().unwrap().clone()).unwrap(); + assert!(initialize_result.capabilities.completion_provider.is_some()); assert_eq!( initialized_workspace.lock().unwrap().as_deref(), Some("file:///tmp") @@ -779,10 +978,60 @@ mod tests { assert_eq!(edits.len(), 1); assert!(edits[0].new_text.ends_with('\n')); + client_connection + .sender + .send(Message::Notification(Notification::new( + String::from("textDocument/didChange"), + json!({ + "textDocument": { "uri": uri, "version": 2 }, + "contentChanges": [{ "text": "Post.dr" }] + }), + ))) + .unwrap(); + let published = client_connection + .receiver + .recv_timeout(Duration::from_secs(2)) + .unwrap(); + assert!(matches!(published, Message::Notification(_))); + client_connection .sender .send(Message::Request(Request { id: RequestId::from(3), + method: String::from("textDocument/completion"), + params: json!({ + "textDocument": { "uri": uri }, + "position": { "line": 0, "character": 7 }, + "context": { "triggerKind": 1 } + }), + })) + .unwrap(); + let completed = client_connection + .receiver + .recv_timeout(Duration::from_secs(2)) + .unwrap(); + let Message::Response(completed) = completed else { + panic!("expected completion response") + }; + let completion: CompletionResponse = + serde_json::from_value(completed.response_result.unwrap()).unwrap(); + let CompletionResponse::Array(items) = completion else { + panic!("expected completion item array") + }; + let draft = items.iter().find(|item| item.label == "draft").unwrap(); + assert_eq!(draft.kind, Some(CompletionItemKind::PROPERTY)); + let Some(CompletionTextEdit::Edit(edit)) = &draft.text_edit else { + panic!("expected completion text edit") + }; + assert_eq!( + edit.range, + Range::new(Position::new(0, 5), Position::new(0, 7)) + ); + + client_connection + .sender + .send(Message::Request(Request { + id: RequestId::from(4), method: String::from("shutdown"), params: json!(null), })) diff --git a/crates/decodal-wasm/Cargo.toml b/crates/decodal-wasm/Cargo.toml index f15b342..1657583 100644 --- a/crates/decodal-wasm/Cargo.toml +++ b/crates/decodal-wasm/Cargo.toml @@ -6,7 +6,7 @@ rust-version.workspace = true license.workspace = true repository.workspace = true readme.workspace = true -description = "WebAssembly wrapper for evaluating Decodal in browser playgrounds." +description = "Host-configurable Decodal evaluator and language service for JavaScript runtimes." keywords = ["decodal", "wasm", "dsl", "config"] categories = ["wasm", "config"] publish = false @@ -16,8 +16,13 @@ crate-type = ["cdylib", "rlib"] [dependencies] decodal = { version = "0.1.2", path = "../decodal-core" } +decodal-language-service = { version = "0.1.2", path = "../decodal-language-service" } serde_json.workspace = true wasm-bindgen.workspace = true +[target.'cfg(target_arch = "wasm32")'.dependencies] +js-sys = "0.3" +serde-wasm-bindgen = "0.6" + [package.metadata.wasm-pack.profile.release] wasm-opt = false diff --git a/crates/decodal-wasm/src/host_value.rs b/crates/decodal-wasm/src/host_value.rs new file mode 100644 index 0000000..e30df7b --- /dev/null +++ b/crates/decodal-wasm/src/host_value.rs @@ -0,0 +1,228 @@ +use decodal::{CompareOp, Constraint, HostValue, LiteralValue, PrimitiveType}; +use serde_json::{Map, Value}; + +pub(crate) fn from_json(value: &Value) -> Result { + match value { + Value::Null => Err(String::from("null is not a Decodal host value")), + Value::Bool(value) => Ok(HostValue::bool(*value)), + Value::Number(value) => number(value), + Value::String(value) => Ok(HostValue::string(value)), + Value::Array(items) => items + .iter() + .enumerate() + .map(|(index, value)| { + from_json(value).map_err(|error| format!("array item {index}: {error}")) + }) + .collect::, _>>() + .map(HostValue::array), + Value::Object(fields) => object(fields), + } +} + +fn number(value: &serde_json::Number) -> Result { + if let Some(value) = value.as_i64() { + return Ok(HostValue::int(value)); + } + if let Some(value) = value.as_u64() { + return i64::try_from(value) + .map(HostValue::int) + .map_err(|_| String::from("integer host value is outside the signed 64-bit range")); + } + value + .as_f64() + .filter(|value| value.is_finite()) + .map(HostValue::float) + .ok_or_else(|| String::from("invalid numeric host value")) +} + +fn object(fields: &Map) -> Result { + let Some(descriptor) = fields.get("$decodal") else { + return fields + .iter() + .map(|(name, value)| { + from_json(value) + .map(|value| (name.clone(), value)) + .map_err(|error| format!("field `{name}`: {error}")) + }) + .collect::, _>>() + .map(HostValue::object); + }; + + let descriptor = descriptor + .as_str() + .ok_or_else(|| String::from("`$decodal` must be a descriptor name"))?; + let constraints = parse_constraints(fields.get("constraints"))?; + let default = fields + .get("default") + .map(from_json) + .transpose()? + .map(Box::new); + + match descriptor { + "String" | "Int" | "Float" | "Bool" => { + let primitive = match descriptor { + "String" => PrimitiveType::String, + "Int" => PrimitiveType::Int, + "Float" => PrimitiveType::Float, + "Bool" => PrimitiveType::Bool, + _ => unreachable!(), + }; + let mut all_constraints = vec![Constraint::Type(primitive)]; + all_constraints.extend(constraints); + Ok(HostValue::Abstract { + constraints: all_constraints, + default, + }) + } + "Array" => { + let item = fields + .get("item") + .ok_or_else(|| String::from("Array descriptor requires `item`"))?; + Ok(HostValue::ArrayConstraint { + item: Box::new(from_json(item)?), + constraints, + default, + }) + } + "Abstract" => Ok(HostValue::Abstract { + constraints, + default, + }), + name => Err(format!("unknown Decodal host descriptor `{name}`")), + } +} + +fn parse_constraints(value: Option<&Value>) -> Result, String> { + let Some(value) = value else { + return Ok(Vec::new()); + }; + let items = value + .as_array() + .ok_or_else(|| String::from("`constraints` must be an array"))?; + items + .iter() + .enumerate() + .map(|(index, value)| { + parse_constraint(value).map_err(|error| format!("constraint {index}: {error}")) + }) + .collect() +} + +fn parse_constraint(value: &Value) -> Result { + let fields = value + .as_object() + .ok_or_else(|| String::from("constraint must be an object"))?; + let kind = required_string(fields, "kind")?; + match kind { + "type" => match required_string(fields, "value")? { + "String" => Ok(Constraint::Type(PrimitiveType::String)), + "Int" => Ok(Constraint::Type(PrimitiveType::Int)), + "Float" => Ok(Constraint::Type(PrimitiveType::Float)), + "Bool" => Ok(Constraint::Type(PrimitiveType::Bool)), + value => Err(format!("unknown primitive type `{value}`")), + }, + "compare" => { + let operation = match required_string(fields, "op")? { + ">" => CompareOp::Gt, + ">=" => CompareOp::Gte, + "<" => CompareOp::Lt, + "<=" => CompareOp::Lte, + operation => return Err(format!("unknown comparison operator `{operation}`")), + }; + let value = fields + .get("value") + .ok_or_else(|| String::from("compare constraint requires `value`"))?; + Ok(Constraint::Compare(operation, literal(value)?)) + } + "regex" => Ok(Constraint::Regex( + required_string(fields, "value")?.to_owned(), + )), + "predicate" => Ok(Constraint::BuiltinPredicate( + required_string(fields, "value")?.to_owned(), + )), + kind => Err(format!("unknown constraint kind `{kind}`")), + } +} + +fn literal(value: &Value) -> Result { + match value { + Value::String(value) => Ok(LiteralValue::String(value.clone())), + Value::Bool(value) => Ok(LiteralValue::Bool(*value)), + Value::Number(value) => match number(value)? { + HostValue::Int(value) => Ok(LiteralValue::Int(value)), + HostValue::Float(value) => Ok(LiteralValue::Float(value)), + _ => unreachable!(), + }, + _ => Err(String::from("comparison value must be a primitive literal")), + } +} + +fn required_string<'a>(fields: &'a Map, name: &str) -> Result<&'a str, String> { + fields + .get(name) + .and_then(Value::as_str) + .ok_or_else(|| format!("constraint requires string `{name}`")) +} + +#[cfg(test)] +mod tests { + use decodal::{Constraint, HostValue, LiteralValue, PrimitiveType}; + + use super::from_json; + + #[test] + fn converts_plain_js_shaped_values() { + let value = serde_json::json!({ + "frontmatter": { "draft": false }, + "body": "# Hello", + }); + assert_eq!( + from_json(&value).unwrap(), + HostValue::object([ + ("body", HostValue::string("# Hello")), + ( + "frontmatter", + HostValue::object([("draft", HostValue::bool(false))]), + ), + ]) + ); + } + + #[test] + fn converts_schema_descriptors() { + let value = serde_json::json!({ + "$decodal": "Array", + "item": { + "$decodal": "Int", + "constraints": [{ "kind": "compare", "op": ">", "value": 0 }], + }, + "default": [1, 2], + }); + assert_eq!( + from_json(&value).unwrap(), + HostValue::ArrayConstraint { + item: Box::new(HostValue::Abstract { + constraints: vec![ + Constraint::Type(PrimitiveType::Int), + Constraint::Compare(decodal::CompareOp::Gt, LiteralValue::Int(0)), + ], + default: None, + }), + constraints: Vec::new(), + default: Some(Box::new(HostValue::array([ + HostValue::int(1), + HostValue::int(2), + ]))), + } + ); + } + + #[test] + fn rejects_null_values() { + assert!( + from_json(&serde_json::Value::Null) + .unwrap_err() + .contains("null") + ); + } +} diff --git a/crates/decodal-wasm/src/lib.rs b/crates/decodal-wasm/src/lib.rs index 5a2705f..494f805 100644 --- a/crates/decodal-wasm/src/lib.rs +++ b/crates/decodal-wasm/src/lib.rs @@ -1,25 +1,67 @@ -use std::collections::BTreeMap; - -use decodal::{ - Data, Diagnostic, DiagnosticKind, EmptyLoader, Engine, ImportLoader, LoadedImport, - LoadedSource, SourceId, Span, format_diagnostic_with, -}; +#[cfg(target_arch = "wasm32")] +use decodal::HostEnvironment; +use decodal::{Data, EmptyLoader, Engine, SourceId, format_diagnostic_with}; +#[cfg(target_arch = "wasm32")] +use decodal_language_service::{CompletionKind, LanguageService}; use wasm_bindgen::prelude::*; +#[cfg(any(target_arch = "wasm32", test))] +mod host_value; +#[cfg(target_arch = "wasm32")] +mod web_environment; + +#[cfg(target_arch = "wasm32")] +use web_environment::JsEnvironment; + +/// Evaluates one standalone Decodal source with no host globals or imports. #[wasm_bindgen] pub fn evaluate(source: &str) -> String { encode_result(evaluate_inner(source)) } -#[wasm_bindgen(js_name = evaluateProject)] -pub fn evaluate_project(entry: &str, files_json: &str) -> String { - encode_result(evaluate_project_inner(entry, files_json)) +/// A browser-facing language service configured entirely by its JavaScript host. +/// +/// The host owns globals, import loading, and import completion. This keeps +/// filesystem, network, and virtual-project policy outside the WASM package. +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen(js_name = DecodalLanguageService)] +pub struct WebLanguageService { + environment: JsEnvironment, +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen(js_class = DecodalLanguageService)] +impl WebLanguageService { + #[wasm_bindgen(constructor)] + pub fn new(options: JsValue) -> Result { + Ok(Self { + environment: JsEnvironment::from_options(options)?, + }) + } + + /// Evaluates a source using the injected globals and import loader. + pub fn evaluate(&self, key: &str, name: &str, source: &str) -> String { + encode_result(evaluate_with_environment( + &self.environment, + key, + name, + source, + )) + } + + /// Completes a source using the same injected environment as evaluation. + /// + /// Positions and returned ranges are UTF-16 offsets, matching browser + /// editors and the Language Server Protocol. + pub fn complete(&self, key: &str, source: &str, position: usize, explicit: bool) -> String { + encode_completion(&self.environment, key, source, position, explicit) + } } fn encode_result(result: Result) -> String { match result { - Ok(output) => format!("{{\"ok\":true,\"output\":{}}}", json_string(&output)), - Err(error) => format!("{{\"ok\":false,\"error\":{}}}", json_string(&error)), + Ok(output) => serde_json::json!({ "ok": true, "output": output }).to_string(), + Err(error) => serde_json::json!({ "ok": false, "error": error }).to_string(), } } @@ -40,103 +82,106 @@ fn evaluate_inner(source: &str) -> Result { Ok(format_data(&data, 0)) } -fn evaluate_project_inner(entry: &str, files_json: &str) -> Result { - let raw_files: BTreeMap = serde_json::from_str(files_json) - .map_err(|error| format!("failed to read playground files: {error}"))?; - let mut files = BTreeMap::new(); - for (path, source) in raw_files { - let path = normalize_path(&path).ok_or_else(|| format!("invalid file path `{path}`"))?; - files.insert(path, source); - } - - let entry = normalize_path(entry).ok_or_else(|| format!("invalid entry path `{entry}`"))?; - let source = files - .get(&entry) - .cloned() - .ok_or_else(|| format!("entry file `{entry}` was not found"))?; - - let mut engine = Engine::new(VirtualLoader { files }); - let module = match engine.add_root_source(entry.clone(), entry.clone(), &source) { +#[cfg(target_arch = "wasm32")] +fn evaluate_with_environment( + environment: &JsEnvironment, + key: &str, + name: &str, + source: &str, +) -> Result { + let mut engine = environment + .create_engine() + .map_err(|diagnostic| diagnostic.message)?; + let module = match engine.add_root_source(key, name, source) { Ok(module) => module, - Err(error) => return Err(format_diagnostic_with_root(&error, &entry)), + Err(diagnostic) => return Err(engine.format_diagnostic(&diagnostic)), }; let value = match engine.eval_module(module) { Ok(value) => value, - Err(error) => return Err(engine.format_diagnostic(&error)), + Err(diagnostic) => return Err(engine.format_diagnostic(&diagnostic)), }; let data = match engine.materialize(&value) { Ok(data) => data, - Err(error) => return Err(engine.format_diagnostic(&error)), + Err(diagnostic) => return Err(engine.format_diagnostic(&diagnostic)), }; Ok(format_data(&data, 0)) } -#[derive(Debug, Clone)] -struct VirtualLoader { - files: BTreeMap, -} - -impl ImportLoader for VirtualLoader { - fn load( - &mut self, - current_key: Option<&str>, - specifier: &str, - ) -> decodal::Result { - let key = resolve_import(current_key, specifier).ok_or_else(|| { - Diagnostic::new( - DiagnosticKind::Import, - Span::default(), - format!("invalid import path `{specifier}`"), - ) - })?; - let source = self.files.get(&key).cloned().ok_or_else(|| { - Diagnostic::new( - DiagnosticKind::Import, - Span::default(), - format!("import `{specifier}` resolved to `{key}`, but that file does not exist"), - ) - })?; - Ok(LoadedImport::Source(LoadedSource { - key: key.clone(), - name: key, - source, - })) - } -} - -fn resolve_import(current_key: Option<&str>, specifier: &str) -> Option { - if specifier.starts_with('/') { - return normalize_path(specifier); - } - - let mut base = String::new(); - if let Some(current_key) = current_key { - if let Some((parent, _file)) = current_key.rsplit_once('/') { - base.push_str(parent); - base.push('/'); +#[cfg(target_arch = "wasm32")] +fn encode_completion( + environment: &JsEnvironment, + key: &str, + source: &str, + position: usize, + explicit: bool, +) -> String { + let byte_position = utf16_offset_to_byte(source, position); + let service = LanguageService::new(environment); + let completion = match service.complete(key, source, byte_position, explicit) { + Ok(completion) => completion, + Err(diagnostic) => { + return serde_json::json!({ + "ok": false, + "error": diagnostic.message, + }) + .to_string(); } - } - base.push_str(specifier); - normalize_path(&base) + }; + let completion = completion.map(|completion| { + let from = byte_offset_to_utf16(source, completion.from); + let options = completion + .items + .into_iter() + .map(|item| { + serde_json::json!({ + "label": item.label, + "kind": completion_kind_name(item.kind), + "detail": item.detail, + "priority": item.priority, + }) + }) + .collect::>(); + serde_json::json!({ "from": from, "options": options }) + }); + serde_json::json!({ "ok": true, "completion": completion }).to_string() } -fn normalize_path(path: &str) -> Option { - let mut parts = Vec::new(); - let normalized = path.replace('\\', "/"); - for part in normalized.split('/') { - match part { - "" | "." => {} - ".." => { - parts.pop()?; - } - part => parts.push(part), +#[cfg(target_arch = "wasm32")] +fn completion_kind_name(kind: CompletionKind) -> &'static str { + match kind { + CompletionKind::Keyword => "keyword", + CompletionKind::Constant => "constant", + CompletionKind::Type => "type", + CompletionKind::Variable => "variable", + CompletionKind::Namespace => "namespace", + CompletionKind::Property => "property", + CompletionKind::File => "file", + } +} + +#[cfg(any(target_arch = "wasm32", test))] +fn utf16_offset_to_byte(source: &str, offset: usize) -> usize { + let mut utf16 = 0usize; + for (byte, ch) in source.char_indices() { + if utf16 >= offset { + return byte; } + let next = utf16 + ch.len_utf16(); + if next > offset { + return byte; + } + utf16 = next; } - if parts.is_empty() { - None - } else { - Some(parts.join("/")) + source.len() +} + +#[cfg(any(target_arch = "wasm32", test))] +fn byte_offset_to_utf16(source: &str, mut offset: usize) -> usize { + offset = offset.min(source.len()); + while !source.is_char_boundary(offset) { + offset = offset.saturating_sub(1); } + source[..offset].encode_utf16().count() } fn format_diagnostic_with_root(diagnostic: &decodal::Diagnostic, root_name: &str) -> String { @@ -191,66 +236,28 @@ fn format_data(data: &Data, indent: usize) -> String { } fn json_string(value: &str) -> String { - let mut out = String::from("\""); - for ch in value.chars() { - match ch { - '"' => out.push_str("\\\""), - '\\' => out.push_str("\\\\"), - '\n' => out.push_str("\\n"), - '\r' => out.push_str("\\r"), - '\t' => out.push_str("\\t"), - ch if ch.is_control() => { - use core::fmt::Write; - let _ = write!(out, "\\u{:04x}", ch as u32); - } - ch => out.push(ch), - } - } - out.push('"'); - out + serde_json::to_string(value).expect("strings are always JSON-serializable") } #[cfg(test)] mod tests { - use super::{evaluate_project_inner, normalize_path, resolve_import}; + use super::{byte_offset_to_utf16, evaluate_inner, utf16_offset_to_byte}; #[test] - fn normalizes_virtual_paths() { + fn evaluates_standalone_sources() { assert_eq!( - normalize_path("/schemas/../main.dcdl"), - Some("main.dcdl".into()) - ); - assert_eq!(normalize_path("../main.dcdl"), None); - } - - #[test] - fn resolves_imports_relative_to_current_file() { - assert_eq!( - resolve_import(Some("schemas/service.dcdl"), "./types.dcdl"), - Some("schemas/types.dcdl".into()) + evaluate_inner("value = 1;").unwrap(), + "{\n \"value\": 1\n}" ); } #[test] - fn evaluates_project_imports() { - let files = r#"{ - "main.dcdl":"let dep = import \"./schemas/service.dcdl\"; in dep.Service & { port = 9443; }", - "schemas/service.dcdl":"Service = { name = String default \"api\"; port = Int & > 443 default 8443; }" - }"#; - let output = evaluate_project_inner("main.dcdl", files).unwrap(); - assert!(output.contains("\"port\": 9443")); - } - - #[test] - fn project_diagnostics_use_virtual_file_names() { - let files = r#"{ - "main.dcdl":"let dep = import \"./schemas/service.dcdl\"; in dep.Service & { port = 80; }", - "schemas/service.dcdl":"Service = { port = Int & > 443 default 8443; }" - }"#; - let error = evaluate_project_inner("main.dcdl", files).unwrap_err(); - assert!(error.contains("main.dcdl:")); - assert!(error.contains("schemas/service.dcdl:")); - assert!(!error.contains("source 0:")); - assert!(!error.contains("source 1:")); + fn converts_web_utf16_offsets() { + let source = "a😀β"; + assert_eq!(utf16_offset_to_byte(source, 0), 0); + assert_eq!(utf16_offset_to_byte(source, 1), 1); + assert_eq!(utf16_offset_to_byte(source, 3), 5); + assert_eq!(byte_offset_to_utf16(source, 5), 3); + assert_eq!(byte_offset_to_utf16(source, source.len()), 4); } } diff --git a/crates/decodal-wasm/src/web_environment.rs b/crates/decodal-wasm/src/web_environment.rs new file mode 100644 index 0000000..25799c3 --- /dev/null +++ b/crates/decodal-wasm/src/web_environment.rs @@ -0,0 +1,209 @@ +use std::collections::BTreeMap; + +use decodal::{ + Diagnostic, DiagnosticKind, Engine, HostEnvironment, HostValue, ImportCandidate, ImportLoader, + LoadedImport, Span, +}; +use js_sys::{Function, Reflect}; +use serde_json::Value; +use wasm_bindgen::{JsCast, JsValue}; + +use crate::host_value; + +pub(crate) struct JsEnvironment { + globals: BTreeMap, + load_import: Option, + complete_import: Option, +} + +impl JsEnvironment { + pub(crate) fn from_options(options: JsValue) -> Result { + if !options.is_null() && !options.is_undefined() && !options.is_object() { + return Err(JsValue::from_str( + "DecodalLanguageService options must be an object", + )); + } + + let globals = property(&options, "globals")?; + let globals = if globals.is_null() || globals.is_undefined() { + BTreeMap::new() + } else { + let globals: Value = serde_wasm_bindgen::from_value(globals).map_err(|error| { + JsValue::from_str(&format!("failed to read `globals`: {error}")) + })?; + let globals = globals.as_object().ok_or_else(|| { + JsValue::from_str("DecodalLanguageService `globals` must be an object") + })?; + globals + .iter() + .map(|(name, value)| { + host_value::from_json(value) + .map(|value| (name.clone(), value)) + .map_err(|error| { + JsValue::from_str(&format!("invalid global `{name}`: {error}")) + }) + }) + .collect::, _>>()? + }; + + Ok(Self { + globals, + load_import: optional_function(&options, "loadImport")?, + complete_import: optional_function(&options, "completeImport")?, + }) + } +} + +impl HostEnvironment for JsEnvironment { + type Loader = JsLoader; + + fn create_loader(&self) -> Self::Loader { + JsLoader { + load_import: self.load_import.clone(), + complete_import: self.complete_import.clone(), + } + } + + fn configure_engine(&self, engine: &mut Engine) -> decodal::Result<()> { + for (name, value) in &self.globals { + engine.bind_global(name, value.clone())?; + } + Ok(()) + } +} + +pub(crate) struct JsLoader { + load_import: Option, + complete_import: Option, +} + +impl ImportLoader for JsLoader { + fn load( + &mut self, + current_key: Option<&str>, + specifier: &str, + ) -> decodal::Result { + let callback = self.load_import.as_ref().ok_or_else(|| { + import_error(format!( + "no JavaScript `loadImport` callback is configured for `{specifier}`" + )) + })?; + let current_key = current_key.map(JsValue::from_str).unwrap_or(JsValue::NULL); + let specifier = JsValue::from_str(specifier); + let loaded = callback + .call2(&JsValue::UNDEFINED, ¤t_key, &specifier) + .map_err(|error| import_error(js_error_message(error)))?; + let loaded: Value = serde_wasm_bindgen::from_value(loaded) + .map_err(|error| import_error(format!("invalid `loadImport` result: {error}")))?; + loaded_import(&loaded).map_err(import_error) + } + + fn complete_import( + &mut self, + current_key: Option<&str>, + prefix: &str, + ) -> decodal::Result> { + let Some(callback) = &self.complete_import else { + return Ok(Vec::new()); + }; + let current_key = current_key.map(JsValue::from_str).unwrap_or(JsValue::NULL); + let prefix = JsValue::from_str(prefix); + let candidates = callback + .call2(&JsValue::UNDEFINED, ¤t_key, &prefix) + .map_err(|error| import_error(js_error_message(error)))?; + let candidates: Value = serde_wasm_bindgen::from_value(candidates) + .map_err(|error| import_error(format!("invalid `completeImport` result: {error}")))?; + import_candidates(&candidates).map_err(import_error) + } +} + +fn loaded_import(value: &Value) -> Result { + let fields = value + .as_object() + .ok_or_else(|| String::from("`loadImport` must return an object"))?; + let kind = string_field(fields, "kind")?; + let key = string_field(fields, "key")?; + match kind { + "source" => { + let source = string_field(fields, "source")?; + let name = fields.get("name").and_then(Value::as_str).unwrap_or(key); + Ok(LoadedImport::source(key, name, source)) + } + "value" => { + let value = fields + .get("value") + .ok_or_else(|| String::from("value import requires `value`"))?; + let value = host_value::from_json(value) + .map_err(|error| format!("invalid imported value: {error}"))?; + Ok(LoadedImport::value(key, value)) + } + kind => Err(format!("unknown `loadImport` result kind `{kind}`")), + } +} + +fn import_candidates(value: &Value) -> Result, String> { + value + .as_array() + .ok_or_else(|| String::from("`completeImport` must return an array"))? + .iter() + .enumerate() + .map(|(index, value)| match value { + Value::String(specifier) => Ok(ImportCandidate::new(specifier)), + Value::Object(fields) => { + let mut candidate = ImportCandidate::new(string_field(fields, "specifier")?); + if let Some(detail) = fields.get("detail") { + let detail = detail.as_str().ok_or_else(|| { + format!("import candidate {index} `detail` must be a string") + })?; + candidate = candidate.with_detail(detail); + } + Ok(candidate) + } + _ => Err(format!( + "import candidate {index} must be a string or object" + )), + }) + .collect() +} + +fn string_field<'a>( + fields: &'a serde_json::Map, + name: &str, +) -> Result<&'a str, String> { + fields + .get(name) + .and_then(Value::as_str) + .ok_or_else(|| format!("`loadImport` result requires string `{name}`")) +} + +fn property(options: &JsValue, name: &str) -> Result { + if options.is_null() || options.is_undefined() { + return Ok(JsValue::UNDEFINED); + } + Reflect::get(options, &JsValue::from_str(name)) +} + +fn optional_function(options: &JsValue, name: &str) -> Result, JsValue> { + let value = property(options, name)?; + if value.is_null() || value.is_undefined() { + return Ok(None); + } + value + .dyn_into::() + .map(Some) + .map_err(|_| JsValue::from_str(&format!("`{name}` must be a function"))) +} + +fn js_error_message(value: JsValue) -> String { + if let Some(message) = value.as_string() { + return message; + } + Reflect::get(&value, &JsValue::from_str("message")) + .ok() + .and_then(|message| message.as_string()) + .unwrap_or_else(|| String::from("JavaScript import callback failed")) +} + +fn import_error(message: impl Into) -> Diagnostic { + Diagnostic::new(DiagnosticKind::Import, Span::default(), message) +} diff --git a/packages/decodal-wasm/README.md b/packages/decodal-wasm/README.md index 27365eb..d2fbf0e 100644 --- a/packages/decodal-wasm/README.md +++ b/packages/decodal-wasm/README.md @@ -2,7 +2,7 @@ WebAssembly runtime package for Decodal. -This package exposes the Decodal evaluator to browsers and other JavaScript runtimes that can load WebAssembly modules. +This package exposes the Decodal evaluator and shared language service to browsers and other JavaScript runtimes that can load WebAssembly modules. It is generated from the Rust crate in `crates/decodal-wasm` with `wasm-pack` and is used by the official playground. Use `decodal-codemirror` separately when you need CodeMirror 6 language support. @@ -22,15 +22,48 @@ deno add jsr:@hare/decodal-wasm ## Usage ```js -import init, { evaluateProject } from 'decodal-wasm'; +import init, { DecodalLanguageService } from 'decodal-wasm'; await init(); -const result = evaluateProject('main.dcdl', JSON.stringify({ - 'main.dcdl': 'Server = { port = Int default 8080; };', -})); +const files = { + 'main.dcdl': 'let schema = import "./schema.dcdl"; in schema.Server', + 'schema.dcdl': 'Server = App.Server & { port = 8080; };', +}; + +const service = new DecodalLanguageService({ + globals: { + App: { + Server: { + port: { $decodal: 'Int' }, + }, + }, + }, + loadImport(_currentKey, specifier) { + const key = specifier.startsWith('./') ? specifier.slice(2) : specifier; + return { kind: 'source', key, name: key, source: files[key] }; + }, + completeImport() { + return ['./schema.dcdl']; + }, +}); + +const result = service.evaluate('main.dcdl', 'main.dcdl', files['main.dcdl']); console.log(JSON.parse(result)); + +const completion = service.complete( + 'main.dcdl', + 'App.Server.po', + 'App.Server.po'.length, + false, +); + +console.log(JSON.parse(completion)); ``` -The exported functions return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures. +`globals`, `loadImport`, and `completeImport` are host-owned. The package does not assume a filesystem or virtual project model. Import callbacks are synchronous; preload or cache remote content before evaluation. + +Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use `{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }` for primitive schemas and `{ $decodal: 'Array', item: value }` for array schemas. Descriptors also accept `constraints` and `default`. + +Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures. diff --git a/packages/decodal-wasm/decodal_wasm.d.ts b/packages/decodal-wasm/decodal_wasm.d.ts index e88b72f..d691d47 100644 --- a/packages/decodal-wasm/decodal_wasm.d.ts +++ b/packages/decodal-wasm/decodal_wasm.d.ts @@ -1,20 +1,105 @@ /* tslint:disable */ /* eslint-disable */ -export function evaluate(source: string): string; +/** A concrete JavaScript value or Decodal schema descriptor supplied by the host. */ +export type DecodalHostValue = + | string + | number + | boolean + | DecodalHostValue[] + | { [field: string]: DecodalHostValue } + | DecodalPrimitiveDescriptor + | DecodalArrayDescriptor + | DecodalAbstractDescriptor; -export function evaluateProject(entry: string, files_json: string): string; +export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool'; + +export type DecodalConstraint = + | { kind: 'type'; value: DecodalPrimitiveType } + | { kind: 'compare'; op: '>' | '>=' | '<' | '<='; value: string | number | boolean } + | { kind: 'regex'; value: string } + | { kind: 'predicate'; value: string }; + +export interface DecodalPrimitiveDescriptor { + $decodal: DecodalPrimitiveType; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export interface DecodalArrayDescriptor { + $decodal: 'Array'; + item: DecodalHostValue; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export interface DecodalAbstractDescriptor { + $decodal: 'Abstract'; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export type DecodalLoadedImport = + | { kind: 'source'; key: string; name?: string; source: string } + | { kind: 'value'; key: string; value: DecodalHostValue }; + +export type DecodalImportCandidate = + | string + | { specifier: string; detail?: string }; + +/** Host-owned environment shared by evaluation and language tooling. */ +export interface DecodalEnvironment { + globals?: Record; + /** Synchronous import callback. Preload or cache asynchronous resources first. */ + loadImport?: (currentKey: string | null, specifier: string) => DecodalLoadedImport; + /** Synchronous import completion callback. */ + completeImport?: (currentKey: string | null, prefix: string) => DecodalImportCandidate[]; +} + +/** + * A browser-facing language service configured entirely by its JavaScript host. + * + * The host owns globals, import loading, and import completion. This keeps + * filesystem, network, and virtual-project policy outside the WASM package. + */ +export class DecodalLanguageService { + free(): void; + [Symbol.dispose](): void; + /** + * Completes a source using the same injected environment as evaluation. + * + * Positions and returned ranges are UTF-16 offsets, matching browser + * editors and the Language Server Protocol. + */ + complete(key: string, source: string, position: number, explicit: boolean): string; + /** + * Evaluates a source using the injected globals and import loader. + */ + evaluate(key: string, name: string, source: string): string; + constructor(options?: DecodalEnvironment); +} + +/** + * Evaluates one standalone Decodal source with no host globals or imports. + */ +export function evaluate(source: string): string; export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; export interface InitOutput { readonly memory: WebAssembly.Memory; + readonly __wbg_decodallanguageservice_free: (a: number, b: number) => void; + readonly decodallanguageservice_complete: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number]; + readonly decodallanguageservice_evaluate: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number]; + readonly decodallanguageservice_new: (a: any) => [number, number, number]; readonly evaluate: (a: number, b: number) => [number, number]; - readonly evaluateProject: (a: number, b: number, c: number, d: number) => [number, number]; - readonly __wbindgen_externrefs: WebAssembly.Table; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_exn_store: (a: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_externrefs: WebAssembly.Table; readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __externref_table_dealloc: (a: number) => void; readonly __wbindgen_start: () => void; } diff --git a/packages/decodal-wasm/decodal_wasm.js b/packages/decodal-wasm/decodal_wasm.js index 800a76f..80c07ca 100644 --- a/packages/decodal-wasm/decodal_wasm.js +++ b/packages/decodal-wasm/decodal_wasm.js @@ -1,6 +1,91 @@ /* @ts-self-types="./decodal_wasm.d.ts" */ /** + * A browser-facing language service configured entirely by its JavaScript host. + * + * The host owns globals, import loading, and import completion. This keeps + * filesystem, network, and virtual-project policy outside the WASM package. + */ +export class DecodalLanguageService { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + DecodalLanguageServiceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_decodallanguageservice_free(ptr, 0); + } + /** + * Completes a source using the same injected environment as evaluation. + * + * Positions and returned ranges are UTF-16 offsets, matching browser + * editors and the Language Server Protocol. + * @param {string} key + * @param {string} source + * @param {number} position + * @param {boolean} explicit + * @returns {string} + */ + complete(key, source, position, explicit) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.decodallanguageservice_complete(this.__wbg_ptr, ptr0, len0, ptr1, len1, position, explicit); + deferred3_0 = ret[0]; + deferred3_1 = ret[1]; + return getStringFromWasm0(ret[0], ret[1]); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } + } + /** + * Evaluates a source using the injected globals and import loader. + * @param {string} key + * @param {string} name + * @param {string} source + * @returns {string} + */ + evaluate(key, name, source) { + let deferred4_0; + let deferred4_1; + try { + const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.decodallanguageservice_evaluate(this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2); + deferred4_0 = ret[0]; + deferred4_1 = ret[1]; + return getStringFromWasm0(ret[0], ret[1]); + } finally { + wasm.__wbindgen_free(deferred4_0, deferred4_1, 1); + } + } + /** + * @param {any} options + */ + constructor(options) { + const ret = wasm.decodallanguageservice_new(options); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + this.__wbg_ptr = ret[0]; + DecodalLanguageServiceFinalization.register(this, this.__wbg_ptr, this); + return this; + } +} +if (Symbol.dispose) DecodalLanguageService.prototype[Symbol.dispose] = DecodalLanguageService.prototype.free; + +/** + * Evaluates one standalone Decodal source with no host globals or imports. * @param {string} source * @returns {string} */ @@ -18,31 +103,204 @@ export function evaluate(source) { wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); } } - -/** - * @param {string} entry - * @param {string} files_json - * @returns {string} - */ -export function evaluateProject(entry, files_json) { - let deferred3_0; - let deferred3_1; - try { - const ptr0 = passStringToWasm0(entry, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(files_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ret = wasm.evaluateProject(ptr0, len0, ptr1, len1); - deferred3_0 = ret[0]; - deferred3_1 = ret[1]; - return getStringFromWasm0(ret[0], ret[1]); - } finally { - wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); - } -} function __wbg_get_imports() { const import0 = { __proto__: null, + __wbg_Error_fdd633d4bb5dd76a: function(arg0, arg1) { + const ret = Error(getStringFromWasm0(arg0, arg1)); + return ret; + }, + __wbg_String_8564e559799eccda: function(arg0, arg1) { + const ret = String(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_bigint_get_as_i64_d9e915702856f831: function(arg0, arg1) { + const v = arg1; + const ret = typeof(v) === 'bigint' ? v : undefined; + getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }, + __wbg___wbindgen_boolean_get_edaed31a367ce1bd: function(arg0) { + const v = arg0; + const ret = typeof(v) === 'boolean' ? v : undefined; + return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0; + }, + __wbg___wbindgen_debug_string_8a447059637473e2: function(arg0, arg1) { + const ret = debugString(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_in_4990f46af709e33c: function(arg0, arg1) { + const ret = arg0 in arg1; + return ret; + }, + __wbg___wbindgen_is_bigint_90b5ccfe67c78460: function(arg0) { + const ret = typeof(arg0) === 'bigint'; + return ret; + }, + __wbg___wbindgen_is_function_acc5528be2b923f2: function(arg0) { + const ret = typeof(arg0) === 'function'; + return ret; + }, + __wbg___wbindgen_is_null_6d937fbfb6478470: function(arg0) { + const ret = arg0 === null; + return ret; + }, + __wbg___wbindgen_is_object_0beba4a1980d3eea: function(arg0) { + const val = arg0; + const ret = typeof(val) === 'object' && val !== null; + return ret; + }, + __wbg___wbindgen_is_undefined_721f8decd50c87a3: function(arg0) { + const ret = arg0 === undefined; + return ret; + }, + __wbg___wbindgen_jsval_eq_4e8c38722cb8ff51: function(arg0, arg1) { + const ret = arg0 === arg1; + return ret; + }, + __wbg___wbindgen_jsval_loose_eq_4b9aba9e5b3c4582: function(arg0, arg1) { + const ret = arg0 == arg1; + return ret; + }, + __wbg___wbindgen_number_get_1cc01dd708740256: function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'number' ? obj : undefined; + getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }, + __wbg___wbindgen_string_get_71bb4348194e31f0: function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }, + __wbg___wbindgen_throw_ea4887a5f8f9a9db: function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }, + __wbg_call_0e855b388e315e17: function() { return handleError(function (arg0, arg1, arg2, arg3) { + const ret = arg0.call(arg1, arg2, arg3); + return ret; + }, arguments); }, + __wbg_call_8e98ed2f3c86c4b5: function() { return handleError(function (arg0, arg1) { + const ret = arg0.call(arg1); + return ret; + }, arguments); }, + __wbg_done_b62d4a7d2286852a: function(arg0) { + const ret = arg0.done; + return ret; + }, + __wbg_entries_c261c3fa1f281256: function(arg0) { + const ret = Object.entries(arg0); + return ret; + }, + __wbg_get_197a3fe98f169e38: function(arg0, arg1) { + const ret = arg0[arg1 >>> 0]; + return ret; + }, + __wbg_get_9a29be2cb383ed9a: function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(arg0, arg1); + return ret; + }, arguments); }, + __wbg_get_dddb90ff5d27a080: function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(arg0, arg1); + return ret; + }, arguments); }, + __wbg_get_unchecked_54a4374c38e08460: function(arg0, arg1) { + const ret = arg0[arg1 >>> 0]; + return ret; + }, + __wbg_instanceof_ArrayBuffer_2a7bb09fee70c2da: function(arg0) { + let result; + try { + result = arg0 instanceof ArrayBuffer; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_instanceof_Map_afa18d5840c04c15: function(arg0) { + let result; + try { + result = arg0 instanceof Map; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_instanceof_Uint8Array_f080092dc70f5d58: function(arg0) { + let result; + try { + result = arg0 instanceof Uint8Array; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }, + __wbg_isArray_145a34fd0a38d37b: function(arg0) { + const ret = Array.isArray(arg0); + return ret; + }, + __wbg_isSafeInteger_a3389a198582f5f6: function(arg0) { + const ret = Number.isSafeInteger(arg0); + return ret; + }, + __wbg_iterator_cc47ba25a2be735a: function() { + const ret = Symbol.iterator; + return ret; + }, + __wbg_length_589238bdcf171f0e: function(arg0) { + const ret = arg0.length; + return ret; + }, + __wbg_length_c6054974c0a6cdb9: function(arg0) { + const ret = arg0.length; + return ret; + }, + __wbg_new_81880fb5002cb255: function(arg0) { + const ret = new Uint8Array(arg0); + return ret; + }, + __wbg_next_0c4066e251d2eff9: function() { return handleError(function (arg0) { + const ret = arg0.next(); + return ret; + }, arguments); }, + __wbg_next_402fa10b59ab20c3: function(arg0) { + const ret = arg0.next; + return ret; + }, + __wbg_prototypesetcall_d721637c7ca66eb8: function(arg0, arg1, arg2) { + Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2); + }, + __wbg_value_49f783bb59765962: function(arg0) { + const ret = arg0.value; + return ret; + }, + __wbindgen_cast_0000000000000001: function(arg0) { + // Cast intrinsic for `I64 -> Externref`. + const ret = arg0; + return ret; + }, + __wbindgen_cast_0000000000000002: function(arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }, + __wbindgen_cast_0000000000000003: function(arg0) { + // Cast intrinsic for `U64 -> Externref`. + const ret = BigInt.asUintN(64, arg0); + return ret; + }, __wbindgen_init_externref_table: function() { const table = wasm.__wbindgen_externrefs; const offset = table.grow(4); @@ -59,6 +317,94 @@ function __wbg_get_imports() { }; } +const DecodalLanguageServiceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_decodallanguageservice_free(ptr, 1)); + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches && builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} + +let cachedDataViewMemory0 = null; +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + function getStringFromWasm0(ptr, len) { return decodeText(ptr >>> 0, len); } @@ -71,6 +417,19 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + function passStringToWasm0(arg, malloc, realloc) { if (realloc === undefined) { const buf = cachedTextEncoder.encode(arg); @@ -108,6 +467,12 @@ function passStringToWasm0(arg, malloc, realloc) { return ptr; } +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_externrefs.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); cachedTextDecoder.decode(); const MAX_SAFARI_DECODE_BYTES = 2146435072; @@ -142,6 +507,7 @@ function __wbg_finalize_init(instance, module) { wasmInstance = instance; wasm = instance.exports; wasmModule = module; + cachedDataViewMemory0 = null; cachedUint8ArrayMemory0 = null; wasm.__wbindgen_start(); return wasm; diff --git a/packages/decodal-wasm/decodal_wasm_bg.wasm b/packages/decodal-wasm/decodal_wasm_bg.wasm index b49e380938b1046f1eec283188b5b2e40530bceb..eefa87d4b22e47aa34dd24dd612ef14d207d923c 100644 GIT binary patch literal 514012 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�R~p4{CkDD-YR; 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 z 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%0Dx$$$Io8H=yH<%PcCmwqAI=NETY9y{sv4;{So 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

#=#oyvhZQb;VcR;|jVmwWw1gmKBJ*qWsegWtZS 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 diff --git a/packages/decodal-wasm/decodal_wasm_bg.wasm.d.ts b/packages/decodal-wasm/decodal_wasm_bg.wasm.d.ts index 4f894cc..80e82f2 100644 --- a/packages/decodal-wasm/decodal_wasm_bg.wasm.d.ts +++ b/packages/decodal-wasm/decodal_wasm_bg.wasm.d.ts @@ -1,10 +1,16 @@ /* tslint:disable */ /* eslint-disable */ export const memory: WebAssembly.Memory; +export const __wbg_decodallanguageservice_free: (a: number, b: number) => void; +export const decodallanguageservice_complete: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number]; +export const decodallanguageservice_evaluate: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number]; +export const decodallanguageservice_new: (a: any) => [number, number, number]; export const evaluate: (a: number, b: number) => [number, number]; -export const evaluateProject: (a: number, b: number, c: number, d: number) => [number, number]; -export const __wbindgen_externrefs: WebAssembly.Table; export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __wbindgen_exn_store: (a: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_externrefs: WebAssembly.Table; export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __externref_table_dealloc: (a: number) => void; export const __wbindgen_start: () => void; diff --git a/packages/decodal-wasm/mod.ts b/packages/decodal-wasm/mod.ts index c67e7fb..cf50ca8 100644 --- a/packages/decodal-wasm/mod.ts +++ b/packages/decodal-wasm/mod.ts @@ -1,66 +1,26 @@ /** - * Browser and JavaScript runtime bindings for the Decodal evaluator. - * - * This module wraps the wasm-bindgen output generated from the Rust - * `decodal-wasm` crate and exposes stable, documented entrypoints for JSR - * users. The exported evaluator functions return JSON strings. + * Host-configurable Decodal evaluator and language service for JavaScript. * * @module */ -import initWasm, { - evaluate as evaluateImpl, - evaluateProject as evaluateProjectImpl, - initSync as initSyncImpl, +export { + DecodalLanguageService, + default, + evaluate, + initSync, } from './decodal_wasm.js'; -/** Input accepted by the wasm-bindgen initializer. */ -export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; - -/** Initialized Decodal WebAssembly exports. */ -export interface InitOutput { - /** Linear memory exported by the WebAssembly module. */ - readonly memory: WebAssembly.Memory; - readonly evaluate: (source: number, len: number) => [number, number, number, number]; - readonly evaluateProject: (entry: number, entryLen: number, files: number, filesLen: number) => [number, number, number, number]; -} - -/** - * Initialize the Decodal WebAssembly runtime asynchronously. - * - * @param moduleOrPath - Optional WebAssembly module, bytes, response, URL, or request. - * @returns The initialized WebAssembly exports. - */ -export default async function initDecodalRuntime(moduleOrPath?: InitInput): Promise { - return await initWasm(moduleOrPath) as InitOutput; -} - -/** - * Initialize the Decodal WebAssembly runtime synchronously. - * - * @param module - Compiled module, bytes, or wasm-bindgen sync initialization input. - * @returns The initialized WebAssembly exports. - */ -export function initSync(module: WebAssembly.Module | BufferSource): InitOutput { - return initSyncImpl(module) as InitOutput; -} - -/** - * Evaluate and materialize a single Decodal source string. - * - * @param source - Decodal source text. - * @returns A JSON string containing either `{ ok: true, output }` or `{ ok: false, error }`. - */ -export function evaluate(source: string): string { - return evaluateImpl(source); -} - -/** - * Evaluate and materialize a virtual multi-file Decodal project. - * - * @param entry - Entry point file path to materialize. - * @param filesJson - JSON object mapping virtual file paths to source strings. - * @returns A JSON string containing either `{ ok: true, output }` or `{ ok: false, error }`. - */ -export function evaluateProject(entry: string, filesJson: string): string { - return evaluateProjectImpl(entry, filesJson); -} +export type { + DecodalAbstractDescriptor, + DecodalArrayDescriptor, + DecodalConstraint, + DecodalEnvironment, + DecodalHostValue, + DecodalImportCandidate, + DecodalLoadedImport, + DecodalPrimitiveDescriptor, + DecodalPrimitiveType, + InitInput, + InitOutput, + SyncInitInput, +} from './decodal_wasm.js'; diff --git a/packages/decodal-wasm/package.json b/packages/decodal-wasm/package.json index dbcd228..9a8c4b3 100644 --- a/packages/decodal-wasm/package.json +++ b/packages/decodal-wasm/package.json @@ -1,7 +1,7 @@ { "name": "decodal-wasm", "type": "module", - "description": "WebAssembly wrapper for evaluating Decodal in browser playgrounds.", + "description": "Host-configurable Decodal evaluator and language service for JavaScript runtimes.", "version": "0.1.3", "license": "MIT OR Apache-2.0", "repository": { diff --git a/site/decodal-site/scripts/prepare-wasm-package.mjs b/site/decodal-site/scripts/prepare-wasm-package.mjs index 733a930..672612e 100644 --- a/site/decodal-site/scripts/prepare-wasm-package.mjs +++ b/site/decodal-site/scripts/prepare-wasm-package.mjs @@ -3,6 +3,73 @@ import { resolve } from 'node:path'; const packageDir = resolve(import.meta.dirname, '../../../packages/decodal-wasm'); +const declarationPath = resolve(packageDir, 'decodal_wasm.d.ts'); +let declarations = readFileSync(declarationPath, 'utf8'); +const hostTypes = ` +/** A concrete JavaScript value or Decodal schema descriptor supplied by the host. */ +export type DecodalHostValue = + | string + | number + | boolean + | DecodalHostValue[] + | { [field: string]: DecodalHostValue } + | DecodalPrimitiveDescriptor + | DecodalArrayDescriptor + | DecodalAbstractDescriptor; + +export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool'; + +export type DecodalConstraint = + | { kind: 'type'; value: DecodalPrimitiveType } + | { kind: 'compare'; op: '>' | '>=' | '<' | '<='; value: string | number | boolean } + | { kind: 'regex'; value: string } + | { kind: 'predicate'; value: string }; + +export interface DecodalPrimitiveDescriptor { + $decodal: DecodalPrimitiveType; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export interface DecodalArrayDescriptor { + $decodal: 'Array'; + item: DecodalHostValue; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export interface DecodalAbstractDescriptor { + $decodal: 'Abstract'; + constraints?: DecodalConstraint[]; + default?: DecodalHostValue; +} + +export type DecodalLoadedImport = + | { kind: 'source'; key: string; name?: string; source: string } + | { kind: 'value'; key: string; value: DecodalHostValue }; + +export type DecodalImportCandidate = + | string + | { specifier: string; detail?: string }; + +/** Host-owned environment shared by evaluation and language tooling. */ +export interface DecodalEnvironment { + globals?: Record; + /** Synchronous import callback. Preload or cache asynchronous resources first. */ + loadImport?: (currentKey: string | null, specifier: string) => DecodalLoadedImport; + /** Synchronous import completion callback. */ + completeImport?: (currentKey: string | null, prefix: string) => DecodalImportCandidate[]; +} +`; +if (!declarations.includes('export interface DecodalEnvironment')) { + declarations = declarations.replace('/* eslint-disable */\n', `/* eslint-disable */\n${hostTypes}`); +} +declarations = declarations.replace( + 'constructor(options: any);', + 'constructor(options?: DecodalEnvironment);', +); +writeFileSync(declarationPath, declarations); + writeFileSync( resolve(packageDir, '.gitignore'), '# wasm-pack output is committed for the browser runtime package.\n', @@ -19,7 +86,7 @@ writeFileSync( WebAssembly runtime package for Decodal. -This package exposes the Decodal evaluator to browsers and other JavaScript runtimes that can load WebAssembly modules. +This package exposes the Decodal evaluator and shared language service to browsers and other JavaScript runtimes that can load WebAssembly modules. It is generated from the Rust crate in \`crates/decodal-wasm\` with \`wasm-pack\` and is used by the official playground. Use \`decodal-codemirror\` separately when you need CodeMirror 6 language support. @@ -39,18 +106,51 @@ deno add jsr:@hare/decodal-wasm ## Usage \`\`\`js -import init, { evaluateProject } from 'decodal-wasm'; +import init, { DecodalLanguageService } from 'decodal-wasm'; await init(); -const result = evaluateProject('main.dcdl', JSON.stringify({ - 'main.dcdl': 'Server = { port = Int default 8080; };', -})); +const files = { + 'main.dcdl': 'let schema = import "./schema.dcdl"; in schema.Server', + 'schema.dcdl': 'Server = App.Server & { port = 8080; };', +}; + +const service = new DecodalLanguageService({ + globals: { + App: { + Server: { + port: { $decodal: 'Int' }, + }, + }, + }, + loadImport(_currentKey, specifier) { + const key = specifier.startsWith('./') ? specifier.slice(2) : specifier; + return { kind: 'source', key, name: key, source: files[key] }; + }, + completeImport() { + return ['./schema.dcdl']; + }, +}); + +const result = service.evaluate('main.dcdl', 'main.dcdl', files['main.dcdl']); console.log(JSON.parse(result)); + +const completion = service.complete( + 'main.dcdl', + 'App.Server.po', + 'App.Server.po'.length, + false, +); + +console.log(JSON.parse(completion)); \`\`\` -The exported functions return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures. +\`globals\`, \`loadImport\`, and \`completeImport\` are host-owned. The package does not assume a filesystem or virtual project model. Import callbacks are synchronous; preload or cache remote content before evaluation. + +Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive schemas and \`{ $decodal: 'Array', item: value }\` for array schemas. Descriptors also accept \`constraints\` and \`default\`. + +Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures. `, ); diff --git a/site/decodal-site/src/scripts/playground-completion.js b/site/decodal-site/src/scripts/playground-completion.js index 97dea80..7f50f6c 100644 --- a/site/decodal-site/src/scripts/playground-completion.js +++ b/site/decodal-site/src/scripts/playground-completion.js @@ -1,256 +1,46 @@ -import { parser } from 'decodal-codemirror/parser'; +const completionTypes = { + keyword: 'keyword', + constant: 'constant', + type: 'type', + variable: 'variable', + namespace: 'namespace', + property: 'property', + file: 'text', +}; -const identifierPattern = /[A-Za-z_][A-Za-z0-9_]*$/; -const memberPattern = /([A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*)\.([A-Za-z_][A-Za-z0-9_]*)?$/; -const importPattern = /\bimport\s+"([^"\n]*)$/; - -const builtinCompletions = [ - { label: 'let', type: 'keyword', detail: 'local bindings', boost: 5 }, - { label: 'in', type: 'keyword', detail: 'let body' }, - { label: 'match', type: 'keyword', detail: 'pattern matching', boost: 5 }, - { label: 'import', type: 'keyword', detail: 'load a module', boost: 5 }, - { label: 'default', type: 'keyword', detail: 'fallback value' }, - { label: 'true', type: 'constant', detail: 'Bool' }, - { label: 'false', type: 'constant', detail: 'Bool' }, - { label: 'String', type: 'type', detail: 'string constraint', boost: 5 }, - { label: 'Int', type: 'type', detail: 'integer constraint', boost: 5 }, - { label: 'Float', type: 'type', detail: 'float constraint', boost: 5 }, - { label: 'Bool', type: 'type', detail: 'boolean constraint', boost: 5 }, -]; - -export function createProjectCompletionSource({ getFiles, getActivePath }) { - return (context) => getProjectCompletions({ - source: context.state.doc.toString(), - position: context.pos, - explicit: context.explicit, - files: getFiles(), - activePath: getActivePath(), - }); -} - -export function getProjectCompletions({ - source, - position, - explicit = false, - files = {}, - activePath = '', -}) { - const before = source.slice(0, position); - const projectFiles = new Map(Object.entries(files)); - const normalizedActivePath = normalizePath(activePath); - if (normalizedActivePath) projectFiles.set(normalizedActivePath, source); - - const importMatch = before.match(importPattern); - if (importMatch) { - return completeImportPath(position, importMatch[1], projectFiles, normalizedActivePath); - } - - if (isLiteralOrComment(source, position)) return null; - - const memberMatch = before.match(memberPattern); - if (memberMatch) { - return completeMemberPath({ - source, - position, - basePath: memberMatch[1], - prefix: memberMatch[2] ?? '', - files: projectFiles, - activePath: normalizedActivePath, - }); - } - - const word = before.match(identifierPattern); - if (!word && !explicit) return null; - const options = [...builtinCompletions]; - const currentFields = collectFieldTree(source); - for (const [label, children] of currentFields) { - options.push({ - label, - type: children.size ? 'namespace' : 'variable', - detail: children.size ? 'local object' : 'local value', - boost: 20, - }); - } - for (const label of collectParameters(source)) { - options.push({ label, type: 'variable', detail: 'parameter', boost: 20 }); - } - for (const [label, specifier] of collectImportBindings(source)) { - options.push({ label, type: 'namespace', detail: specifier, boost: 30 }); - } - - return { - from: word ? position - word[0].length : position, - options: uniqueOptions(options), - validFor: /^[A-Za-z_][A-Za-z0-9_]*$/, +export function createLanguageServiceCompletionSource({ complete, getActivePath }) { + return (context) => { + const activePath = getActivePath(); + let response; + try { + response = complete({ + key: activePath, + source: context.state.doc.toString(), + position: context.pos, + explicit: context.explicit, + }); + if (!response) return null; + if (typeof response === 'string') response = JSON.parse(response); + } catch (_error) { + // The editor can become interactive just before WASM initialization + // finishes. A later completion request will use the initialized service. + return null; + } + if (!response.ok || !response.completion) return null; + return completionResultToCodeMirror(response.completion); }; } -function completeImportPath(position, prefix, files, activePath) { - const options = []; - for (const path of [...files.keys()].sort()) { - if (!path || path === activePath) continue; - const label = prefix.startsWith('/') - ? `/${path}` - : relativeImportPath(activePath, path); - options.push({ - label, - apply: label, - type: 'text', - detail: 'project file', - }); - } +export function completionResultToCodeMirror(completion) { + const fileCompletion = completion.options.some((option) => option.kind === 'file'); return { - from: position - prefix.length, - options, - validFor: /^[^"\n]*$/, - }; -} - -function completeMemberPath({ source, position, basePath, prefix, files, activePath }) { - const parts = basePath.split('.'); - const imports = collectImportBindings(source); - let fields; - let detail = basePath; - - const importSpecifier = imports.get(parts[0]); - if (importSpecifier) { - const importedPath = resolveImportPath(activePath, importSpecifier); - const importedSource = importedPath ? files.get(importedPath) : undefined; - if (importedSource === undefined) return null; - fields = collectFieldTree(importedSource); - parts.shift(); - detail = importedPath; - } else { - fields = collectFieldTree(source); - } - - for (const part of parts) { - fields = fields.get(part); - if (!fields) return null; - } - - return { - from: position - prefix.length, - options: [...fields.entries()].map(([label, children]) => ({ - label, - type: children.size ? 'namespace' : 'property', - detail, - boost: 30, + from: completion.from, + options: completion.options.map((option) => ({ + label: option.label, + type: completionTypes[option.kind] ?? 'text', + detail: option.detail ?? undefined, + boost: option.priority ?? 0, })), - validFor: /^[A-Za-z_][A-Za-z0-9_]*$/, + validFor: fileCompletion ? /^[^"\n]*$/ : /^[A-Za-z_][A-Za-z0-9_]*$/, }; } - -function collectFieldTree(source) { - const fields = new Map(); - collectDefinitions(parser.parse(source).topNode, fields, source); - return fields; -} - -function collectDefinitions(node, target, source) { - for (let child = node.firstChild; child; child = child.nextSibling) { - if (child.name === 'FieldDefinition') { - collectDefinition(child, target, source); - } else { - collectDefinitions(child, target, source); - } - } -} - -function collectDefinition(node, target, source) { - const fieldPath = findDirectChild(node, 'FieldPath'); - if (!fieldPath) return; - const parts = source.slice(fieldPath.from, fieldPath.to).match(/[A-Za-z_][A-Za-z0-9_]*/g); - if (!parts?.length) return; - let nested = target; - for (const part of parts) { - if (!nested.has(part)) nested.set(part, new Map()); - nested = nested.get(part); - } - for (let child = node.firstChild; child; child = child.nextSibling) { - if (child !== fieldPath) collectDefinitions(child, nested, source); - } -} - -function collectParameters(source) { - const parameters = new Set(); - const tree = parser.parse(source); - const visit = (node) => { - for (let child = node.firstChild; child; child = child.nextSibling) { - if (child.name === 'Parameter') { - const identifier = findDirectChild(child, 'Identifier'); - if (identifier) parameters.add(source.slice(identifier.from, identifier.to)); - } - visit(child); - } - }; - visit(tree.topNode); - return parameters; -} - -function collectImportBindings(source) { - const bindings = new Map(); - const pattern = /\b([A-Za-z_][A-Za-z0-9_]*)\s*=\s*import\s+"([^"\n]+)"/g; - for (const match of source.matchAll(pattern)) bindings.set(match[1], match[2]); - return bindings; -} - -function isLiteralOrComment(source, position) { - const tree = parser.parse(source); - let node = tree.resolve(Math.max(0, position - 1), -1); - while (node) { - if (node.name === 'String' || node.name === 'Regex' || node.name === 'Comment') return true; - node = node.parent; - } - return false; -} - -function findDirectChild(node, name) { - for (let child = node.firstChild; child; child = child.nextSibling) { - if (child.name === name) return child; - } - return null; -} - -function resolveImportPath(currentPath, specifier) { - const base = specifier.startsWith('/') - ? [] - : currentPath.split('/').slice(0, -1); - return normalizePath([...base, ...specifier.split('/')].join('/')); -} - -function relativeImportPath(currentPath, targetPath) { - const from = currentPath.split('/').slice(0, -1); - const to = targetPath.split('/'); - while (from.length && to.length && from[0] === to[0]) { - from.shift(); - to.shift(); - } - const relative = [...from.map(() => '..'), ...to].join('/'); - return relative.startsWith('.') ? relative : `./${relative}`; -} - -function normalizePath(path) { - const parts = []; - for (const part of String(path).replaceAll('\\', '/').split('/')) { - if (!part || part === '.') continue; - if (part === '..') { - if (!parts.length) return ''; - parts.pop(); - } else { - parts.push(part); - } - } - return parts.join('/'); -} - -function uniqueOptions(options) { - const unique = new Map(); - for (const option of options) { - const previous = unique.get(option.label); - if (!previous || (option.boost ?? 0) > (previous.boost ?? 0)) { - unique.set(option.label, option); - } - } - return [...unique.values()]; -} diff --git a/site/decodal-site/src/scripts/playground-completion.test.mjs b/site/decodal-site/src/scripts/playground-completion.test.mjs index 997cb71..0f45128 100644 --- a/site/decodal-site/src/scripts/playground-completion.test.mjs +++ b/site/decodal-site/src/scripts/playground-completion.test.mjs @@ -1,81 +1,72 @@ import test from 'node:test'; import assert from 'node:assert/strict'; -import { getProjectCompletions } from './playground-completion.js'; +import { + completionResultToCodeMirror, + createLanguageServiceCompletionSource, +} from './playground-completion.js'; -const files = { - 'main.dcdl': '', - 'schemas/service.dcdl': `Service = { - name = String; - port = Int default 8080; - resources = { cpu = Int; memory = Int; }; -};`, - 'env/production.dcdl': `capacity = { - base_replicas = 6; - cpu_milli = 2000; -};`, -}; - -function complete(source) { - return getProjectCompletions({ - source, - position: source.length, - files, - activePath: 'main.dcdl', +test('passes the active document to an injected language service', () => { + const calls = []; + const source = createLanguageServiceCompletionSource({ + getActivePath: () => 'main.dcdl', + complete(request) { + calls.push(request); + return JSON.stringify({ ok: true, completion: null }); + }, }); -} -test('completes virtual import paths', () => { - const result = complete('schema = import "./sch'); - assert.ok(result.options.some((option) => option.label === './schemas/service.dcdl')); + assert.equal(source({ + state: { doc: { toString: () => 'Post.ti' } }, + pos: 7, + explicit: true, + }), null); + assert.deepEqual(calls, [{ + key: 'main.dcdl', + source: 'Post.ti', + position: 7, + explicit: true, + }]); }); -test('completes imported module fields', () => { - const result = complete('let schema = import "./schemas/service.dcdl"; in schema.'); - assert.deepEqual( - result.options.map((option) => option.label), - ['Service'], - ); -}); - -test('completes nested schema fields', () => { - const result = complete('let schema = import "./schemas/service.dcdl"; in schema.Service.'); - assert.deepEqual( - result.options.map((option) => option.label), - ['name', 'port', 'resources'], - ); -}); - -test('replaces only the partial member name', () => { - const source = 'let schema = import "./schemas/service.dcdl"; in schema.Service.po'; - const result = complete(source); - assert.ok(result.options.some((option) => option.label === 'port')); - assert.equal(result.from, source.length - 2); -}); - -test('completes nested values from another virtual file', () => { - const result = complete('let env = import "./env/production.dcdl"; in env.capacity.'); - assert.deepEqual( - result.options.map((option) => option.label), - ['base_replicas', 'cpu_milli'], - ); -}); - -test('includes language and local binding completions', () => { - const source = 'let service = { port = 8080; }; in ser'; - const result = complete(source); - assert.ok(result.options.some((option) => option.label === 'service')); - assert.ok(result.options.some((option) => option.label === 'String')); - assert.equal(result.from, source.length - 3); -}); - -test('resolves imports relative to nested active files', () => { - const source = 'schema = import "../schemas/serv'; - const result = getProjectCompletions({ - source, - position: source.length, - files, - activePath: 'env/main.dcdl', +test('adapts shared language-service completions for CodeMirror', () => { + const result = completionResultToCodeMirror({ + from: 12, + options: [ + { + label: 'port', + kind: 'property', + detail: 'schemas/service.dcdl', + priority: 30, + }, + ], }); - assert.ok(result.options.some((option) => option.label === '../schemas/service.dcdl')); + + assert.equal(result.from, 12); + assert.deepEqual(result.options, [ + { + label: 'port', + type: 'property', + detail: 'schemas/service.dcdl', + boost: 30, + }, + ]); + assert.ok(result.validFor.test('partial_name')); +}); + +test('uses import-path filtering for file completions', () => { + const result = completionResultToCodeMirror({ + from: 8, + options: [ + { + label: './schemas/service.dcdl', + kind: 'file', + detail: 'project file', + priority: 30, + }, + ], + }); + + assert.ok(result.validFor.test('./schemas/serv')); + assert.equal(result.options[0].type, 'text'); }); diff --git a/site/decodal-site/src/scripts/playground-environment.js b/site/decodal-site/src/scripts/playground-environment.js new file mode 100644 index 0000000..435bc5e --- /dev/null +++ b/site/decodal-site/src/scripts/playground-environment.js @@ -0,0 +1,67 @@ +export function createPlaygroundEnvironment(getFiles) { + return { + globals: {}, + + loadImport(currentKey, specifier) { + const key = resolveImportPath(currentKey, specifier); + const source = getFiles()[key]; + if (source === undefined) { + throw new Error(`import ${JSON.stringify(specifier)} resolved to ${JSON.stringify(key)}, but that file does not exist`); + } + return { kind: 'source', key, name: key, source }; + }, + + completeImport(currentKey, prefix) { + return Object.keys(getFiles()) + .filter((path) => path !== currentKey) + .map((path) => ({ + specifier: prefix.startsWith('/') + ? `/${path}` + : relativeImportPath(currentKey, path), + detail: 'project file', + })) + .filter((candidate) => candidate.specifier.startsWith(prefix)) + .sort((left, right) => left.specifier.localeCompare(right.specifier)); + }, + }; +} + +export function resolveImportPath(currentKey, specifier) { + if (specifier.startsWith('/')) return normalizeVirtualPath(specifier); + const parent = currentKey?.includes('/') + ? currentKey.slice(0, currentKey.lastIndexOf('/')) + : ''; + return normalizeVirtualPath(parent ? `${parent}/${specifier}` : specifier); +} + +export function relativeImportPath(currentKey, target) { + const from = currentKey?.includes('/') + ? currentKey.slice(0, currentKey.lastIndexOf('/')).split('/').filter(Boolean) + : []; + const to = target.split('/').filter(Boolean); + let common = 0; + while (common < from.length && common < to.length && from[common] === to[common]) { + common += 1; + } + const parts = [ + ...Array(from.length - common).fill('..'), + ...to.slice(common), + ]; + const relative = parts.join('/'); + return relative.startsWith('.') ? relative : `./${relative}`; +} + +function normalizeVirtualPath(path) { + const parts = []; + for (const part of String(path).replaceAll('\\', '/').split('/')) { + if (!part || part === '.') continue; + if (part === '..') { + if (parts.length === 0) throw new Error(`invalid virtual path ${JSON.stringify(path)}`); + parts.pop(); + } else { + parts.push(part); + } + } + if (parts.length === 0) throw new Error(`invalid virtual path ${JSON.stringify(path)}`); + return parts.join('/'); +} diff --git a/site/decodal-site/src/scripts/playground-environment.test.mjs b/site/decodal-site/src/scripts/playground-environment.test.mjs new file mode 100644 index 0000000..6f30121 --- /dev/null +++ b/site/decodal-site/src/scripts/playground-environment.test.mjs @@ -0,0 +1,37 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; + +import { + createPlaygroundEnvironment, + relativeImportPath, + resolveImportPath, +} from './playground-environment.js'; + +test('resolves virtual imports in the playground host', () => { + assert.equal( + resolveImportPath('content/pages/home.dcdl', '../schemas/page.dcdl'), + 'content/schemas/page.dcdl', + ); + assert.equal( + relativeImportPath('content/pages/home.dcdl', 'content/schemas/page.dcdl'), + '../schemas/page.dcdl', + ); +}); + +test('loads source and completes paths from playground-owned files', () => { + const files = { + 'main.dcdl': 'import "./schemas/page.dcdl"', + 'schemas/page.dcdl': 'Page = { title = String; };', + }; + const environment = createPlaygroundEnvironment(() => files); + + assert.deepEqual(environment.loadImport('main.dcdl', './schemas/page.dcdl'), { + kind: 'source', + key: 'schemas/page.dcdl', + name: 'schemas/page.dcdl', + source: files['schemas/page.dcdl'], + }); + assert.deepEqual(environment.completeImport('main.dcdl', './sch'), [ + { specifier: './schemas/page.dcdl', detail: 'project file' }, + ]); +}); diff --git a/site/decodal-site/src/scripts/playground-runtime.test.mjs b/site/decodal-site/src/scripts/playground-runtime.test.mjs new file mode 100644 index 0000000..ecb1965 --- /dev/null +++ b/site/decodal-site/src/scripts/playground-runtime.test.mjs @@ -0,0 +1,57 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; + +import initRuntime, { DecodalLanguageService } from 'decodal-wasm'; + +const wasmPath = new URL('../../../../packages/decodal-wasm/decodal_wasm_bg.wasm', import.meta.url); + +test('injects one JavaScript host environment into evaluation and completion', async () => { + await initRuntime({ module_or_path: await readFile(wasmPath) }); + const files = { + 'schema.dcdl': 'Server = { port = Int; };', + }; + const service = new DecodalLanguageService({ + globals: { + App: { + enabled: { $decodal: 'Bool', default: true }, + }, + }, + loadImport(_currentKey, specifier) { + if (specifier === './post.md') { + return { + kind: 'value', + key: 'post.md', + value: { frontmatter: { draft: false }, body: '# Hello' }, + }; + } + return { + kind: 'source', + key: 'schema.dcdl', + source: files['schema.dcdl'], + }; + }, + completeImport() { + return [{ specifier: './schema.dcdl', detail: 'test source' }]; + }, + }); + + const evaluated = JSON.parse(service.evaluate( + 'main.dcdl', + 'main.dcdl', + 'let s = import "./schema.dcdl"; in { server = s.Server & { port = 8080; }; enabled = App.enabled; post = import "./post.md"; }', + )); + assert.equal(evaluated.ok, true, evaluated.error); + assert.match(evaluated.output, /"port": 8080/); + assert.match(evaluated.output, /"body": "# Hello"/); + + const member = JSON.parse(service.complete('main.dcdl', 'App.en', 6, false)); + assert.equal(member.ok, true, member.error); + assert.ok(member.completion.options.some((item) => item.label === 'enabled')); + + const imported = JSON.parse(service.complete('main.dcdl', 'import "./sch', 13, false)); + assert.equal(imported.ok, true, imported.error); + assert.ok(imported.completion.options.some((item) => item.label === './schema.dcdl')); + + service.free(); +}); diff --git a/site/decodal-site/src/scripts/playground.js b/site/decodal-site/src/scripts/playground.js index f93f2c5..82b99fe 100644 --- a/site/decodal-site/src/scripts/playground.js +++ b/site/decodal-site/src/scripts/playground.js @@ -1,4 +1,4 @@ -import initRuntime, { evaluateProject } from 'decodal-wasm'; +import initRuntime, { DecodalLanguageService } from 'decodal-wasm'; import runtimeWasmUrl from 'decodal-wasm/decodal_wasm_bg.wasm?url'; import { EditorView, basicSetup } from 'codemirror'; import { keymap } from '@codemirror/view'; @@ -6,7 +6,8 @@ import { decodal, decodalLanguage } from 'decodal-codemirror'; import { formatDecodal, initDecodalFormatter } from 'decodal-codemirror/format'; import toolsWasmUrl from 'decodal-codemirror/wasm/decodal_language_tools_bg.wasm?url'; import { playgroundExamples } from './playground-examples.js'; -import { createProjectCompletionSource } from './playground-completion.js'; +import { createLanguageServiceCompletionSource } from './playground-completion.js'; +import { createPlaygroundEnvironment } from './playground-environment.js'; const STORAGE_KEY = 'decodal-playground-project-v2'; const starterProject = playgroundExamples[0]; @@ -25,6 +26,7 @@ const entrySelect = document.getElementById('entry-select'); const loadExample = document.getElementById('load-example'); const project = loadProject(); +let languageService; const editorTheme = EditorView.theme({ '&': { @@ -78,9 +80,14 @@ const editorTheme = EditorView.theme({ }, }, { dark: true }); -const completionSource = createProjectCompletionSource({ - getFiles: () => project.files, +const completionSource = createLanguageServiceCompletionSource({ getActivePath: () => project.activePath, + complete: ({ key, source, position, explicit }) => languageService?.complete( + key, + source, + position, + explicit, + ), }); const editor = new EditorView({ @@ -241,7 +248,11 @@ function execute() { project.entryPath = entryPath; updateRunLabel(); saveProject(); - const result = JSON.parse(evaluateProject(entryPath, JSON.stringify(project.files))); + const result = JSON.parse(languageService.evaluate( + entryPath, + entryPath, + project.files[entryPath], + )); output.textContent = result.ok ? result.output : result.error; output.classList.toggle('error', !result.ok); } @@ -312,6 +323,9 @@ function compareNodes(a, b) { try { await Promise.all([initRuntime(runtimeWasmUrl), initDecodalFormatter(toolsWasmUrl)]); + languageService = new DecodalLanguageService( + createPlaygroundEnvironment(() => project.files), + ); run.disabled = false; formatButton.disabled = false; status.textContent = 'Ctrl+Space: complete';