Share host-aware completion across runtimes

This commit is contained in:
2026-08-13 18:55:03 +09:00
parent e862e53f3e
commit d28edcf041
25 changed files with 2836 additions and 578 deletions
+39 -6
View File
@@ -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.
+89 -4
View File
@@ -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<string, DecodalHostValue>;
/** 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;
}
+388 -22
View File
@@ -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;
Binary file not shown.
+8 -2
View File
@@ -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;
+20 -60
View File
@@ -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<InitOutput> {
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';
+1 -1
View File
@@ -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": {