yeptris 0.0.0-stage → 0.6.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -2
- package/dist/yeptris.mjs +16 -0
- package/dist/yeptris.wasm +0 -0
- package/package.json +32 -4
- package/src/index.d.ts +23 -0
- package/src/index.js +116 -0
- package/src/yeptris_wasm.c +109 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 leptris contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
-
#
|
|
1
|
+
# yeptris
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
YAML for JavaScript at [libyeptris](https://github.com/leptris/yeptris)
|
|
4
|
+
speed — the engine compiled to WebAssembly (ES module, no fallback).
|
|
5
|
+
|
|
6
|
+
Part of the yeptris program: *the best (multiple dimensions)
|
|
7
|
+
YAML/JSON parser/builder ever* — conformance, performance,
|
|
8
|
+
safety/hardening, API surfaces, transport correctness, and trust,
|
|
9
|
+
held simultaneously, in C, Ruby, Rust, and JS. This binding is the
|
|
10
|
+
thinnest surface (the WASM module); the recorder bulk-drain and
|
|
11
|
+
iterparse are planned next (the engine's PLAN.md, "The best-ever
|
|
12
|
+
program").
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import { load, dump } from "yeptris";
|
|
16
|
+
|
|
17
|
+
const doc = await load("name: yeptris\nlangs:\n- c\n- rust\n");
|
|
18
|
+
// { name: "yeptris", langs: ["c", "rust"] }
|
|
19
|
+
|
|
20
|
+
const yaml = await dump({ name: "yeptris", langs: ["c", "rust"] });
|
|
21
|
+
// the engine's canonical, byte-stable YAML
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- `load(yaml)` — parse to a JavaScript value (malformed input throws
|
|
25
|
+
`YamlError` with line/column).
|
|
26
|
+
- `loadJSON(yaml)` — the engine's canonical JSON string.
|
|
27
|
+
- `dump(json)` — JSON text (or any JSON-serializable value) to
|
|
28
|
+
canonical YAML; JSON is a subset of YAML 1.2 flow, so the one parse
|
|
29
|
+
engine takes it.
|
|
30
|
+
|
|
31
|
+
The same model as [teptris-wasm](https://github.com/leptris/teptris-wasm):
|
|
32
|
+
a contained C bridge (`src/yeptris_wasm.c`) over the engine's
|
|
33
|
+
buffer-lifetime contract, compiled by `build.sh` (emcc) from the
|
|
34
|
+
sibling engine checkout, surfaced as an ES module.
|
|
35
|
+
|
|
36
|
+
## Build and test
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
./build.sh # ENGINESRC=../yeptris/src by default
|
|
40
|
+
node --test test/test.mjs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
CI builds the engine tag and runs the same on every push and PR.
|
|
44
|
+
|
|
45
|
+
## Releasing
|
|
46
|
+
|
|
47
|
+
`npm publish` runs through the dispatch-only workflow (Trusted
|
|
48
|
+
Publishing — configure `leptris/yeptris-ts` + `release.yml` as the
|
|
49
|
+
package's publisher on npmjs). The first publish is manual; after
|
|
50
|
+
that, dispatch **Release** and the dist build + publish + GitHub
|
|
51
|
+
release run as one train.
|
package/dist/yeptris.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
var Module = (() => {
|
|
3
|
+
var _scriptDir = import.meta.url;
|
|
4
|
+
|
|
5
|
+
return (
|
|
6
|
+
async function(moduleArg = {}) {
|
|
7
|
+
|
|
8
|
+
var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary;if(ENVIRONMENT_IS_NODE){const{createRequire:createRequire}=await import("module");var require=createRequire(import.meta.url);var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=require("url").fileURLToPath(new URL("./",import.meta.url))}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAP64,HEAPU64,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b);Module["HEAP64"]=HEAP64=new BigInt64Array(b);Module["HEAPU64"]=HEAPU64=new BigUint64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");var wasmBinaryFile;if(Module["locateFile"]){wasmBinaryFile="yeptris.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}}else{wasmBinaryFile=new URL("yeptris.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()}).catch(()=>getBinarySync(binaryFile))}}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(instance=>instance).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"a":wasmImports};function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["g"];updateMemoryViews();addOnInit(wasmExports["h"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var noExitRuntime=Module["noExitRuntime"]||true;var getHeapMax=()=>2147483648;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}HEAP8[buffer>>0]=0};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={varargs:undefined,get(){var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret}};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var _fd_close=fd=>52;var MAX_INT53=9007199254740992;var MIN_INT53=-9007199254740992;var bigintToI53Checked=num=>num<MIN_INT53||num>MAX_INT53?NaN:Number(num);function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);return 70}var printCharBuffers=[null,[],[]];var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i<iovcnt;i++){var ptr=HEAPU32[iov>>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j<len;j++){printChar(fd,HEAPU8[ptr+j])}num+=len}HEAPU32[pnum>>2]=num;return 0};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var wasmImports={b:_emscripten_resize_heap,e:_environ_get,f:_environ_sizes_get,d:_fd_close,c:_fd_seek,a:_fd_write};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["h"])();var _yeptris_wasm_load=Module["_yeptris_wasm_load"]=(a0,a1)=>(_yeptris_wasm_load=Module["_yeptris_wasm_load"]=wasmExports["i"])(a0,a1);var _yeptris_wasm_dump=Module["_yeptris_wasm_dump"]=(a0,a1)=>(_yeptris_wasm_dump=Module["_yeptris_wasm_dump"]=wasmExports["j"])(a0,a1);var _yeptris_wasm_last_error=Module["_yeptris_wasm_last_error"]=()=>(_yeptris_wasm_last_error=Module["_yeptris_wasm_last_error"]=wasmExports["k"])();var _yeptris_wasm_last_error_line=Module["_yeptris_wasm_last_error_line"]=()=>(_yeptris_wasm_last_error_line=Module["_yeptris_wasm_last_error_line"]=wasmExports["l"])();var _yeptris_wasm_last_error_column=Module["_yeptris_wasm_last_error_column"]=()=>(_yeptris_wasm_last_error_column=Module["_yeptris_wasm_last_error_column"]=wasmExports["m"])();var _yeptris_wasm_out=Module["_yeptris_wasm_out"]=()=>(_yeptris_wasm_out=Module["_yeptris_wasm_out"]=wasmExports["n"])();var _yeptris_wasm_out_len=Module["_yeptris_wasm_out_len"]=()=>(_yeptris_wasm_out_len=Module["_yeptris_wasm_out_len"]=wasmExports["o"])();var _yeptris_wasm_out_free=Module["_yeptris_wasm_out_free"]=()=>(_yeptris_wasm_out_free=Module["_yeptris_wasm_out_free"]=wasmExports["p"])();var _yeptris_wasm_free=Module["_yeptris_wasm_free"]=a0=>(_yeptris_wasm_free=Module["_yeptris_wasm_free"]=wasmExports["q"])(a0);var _yeptris_wasm_version=Module["_yeptris_wasm_version"]=()=>(_yeptris_wasm_version=Module["_yeptris_wasm_version"]=wasmExports["r"])();var _malloc=Module["_malloc"]=a0=>(_malloc=Module["_malloc"]=wasmExports["t"])(a0);var ___errno_location=()=>(___errno_location=wasmExports["__errno_location"])();Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
return moduleArg.ready
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
})();
|
|
15
|
+
;
|
|
16
|
+
export default Module;
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yeptris",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.6.54",
|
|
4
|
+
"description": "YAML for JavaScript at libyeptris speed (WebAssembly, no fallback)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"types": "src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "./build.sh",
|
|
20
|
+
"test": "node --test test/test.mjs"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/leptris/yeptris-ts.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/leptris/yeptris-ts/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/leptris/yeptris-ts#readme"
|
|
34
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Type declarations for yeptris (the wasm binding).
|
|
2
|
+
export declare class YamlError extends Error {
|
|
3
|
+
line: number;
|
|
4
|
+
column: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/** Parse YAML text and return the document as a JavaScript value
|
|
8
|
+
* (the engine's canonical JSON, JSON.parse'd). Throws YamlError with
|
|
9
|
+
* line/column on malformed input. */
|
|
10
|
+
export declare function load(yaml: string): Promise<unknown>;
|
|
11
|
+
|
|
12
|
+
/** Parse YAML text and return the engine's canonical JSON string. */
|
|
13
|
+
export declare function loadJSON(yaml: string): Promise<string>;
|
|
14
|
+
|
|
15
|
+
/** Convert JSON text (or any JSON-serializable value) to the engine's
|
|
16
|
+
* canonical, byte-stable YAML. */
|
|
17
|
+
export declare function dump(json: string | unknown): Promise<string>;
|
|
18
|
+
|
|
19
|
+
/** The libyeptris version string. */
|
|
20
|
+
export declare function version(): Promise<string>;
|
|
21
|
+
|
|
22
|
+
/** The wasm module instance the package caches (diagnostics). */
|
|
23
|
+
export declare function wasmModule(): Promise<Record<string, unknown>>;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// The public surface: YAML <-> JSON at libyeptris speed.
|
|
2
|
+
// Engine FFI through ../dist/yeptris.mjs (built by build.sh).
|
|
3
|
+
|
|
4
|
+
function cstr(mod, s) {
|
|
5
|
+
const bytes = mod.lengthBytesUTF8(s) + 1;
|
|
6
|
+
const ptr = mod._malloc(bytes);
|
|
7
|
+
mod.stringToUTF8(s, ptr, bytes);
|
|
8
|
+
return [ptr, bytes - 1]; // bytes - 1: the NUL is ours, not the input's
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function freeCstr(mod, ptr) {
|
|
12
|
+
mod._yeptris_wasm_free(ptr);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class YamlError extends Error {
|
|
16
|
+
constructor(message, line, column) {
|
|
17
|
+
super(line ? `${message} (line ${line}, column ${column})` : message);
|
|
18
|
+
this.name = "YamlError";
|
|
19
|
+
this.line = line;
|
|
20
|
+
this.column = column;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function run(mod, fn, input) {
|
|
25
|
+
const [ptr, len] = cstr(mod, input);
|
|
26
|
+
try {
|
|
27
|
+
// len is the UTF-8 byte count: input.length counts UTF-16 code
|
|
28
|
+
// units, which is strictly shorter than the wire bytes for any
|
|
29
|
+
// non-ASCII text (é is 1 unit / 2 bytes) — every such document
|
|
30
|
+
// parsed truncated
|
|
31
|
+
const st = fn(ptr, len);
|
|
32
|
+
if (st !== 0) {
|
|
33
|
+
const msg = mod.UTF8ToString(mod._yeptris_wasm_last_error());
|
|
34
|
+
throw new YamlError(
|
|
35
|
+
msg,
|
|
36
|
+
mod._yeptris_wasm_last_error_line(),
|
|
37
|
+
mod._yeptris_wasm_last_error_column());
|
|
38
|
+
}
|
|
39
|
+
const out = mod.UTF8ToString(mod._yeptris_wasm_out(), mod._yeptris_wasm_out_len());
|
|
40
|
+
return out;
|
|
41
|
+
} finally {
|
|
42
|
+
freeCstr(mod, ptr);
|
|
43
|
+
// the C side mallocs the output per call and nothing else freed
|
|
44
|
+
// it — without this a long-running process grows the wasm heap by
|
|
45
|
+
// one output per call
|
|
46
|
+
mod._yeptris_wasm_out_free();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let cached = null;
|
|
51
|
+
|
|
52
|
+
async function mod() {
|
|
53
|
+
if (cached) return cached;
|
|
54
|
+
const factory = (await import("../dist/yeptris.mjs")).default;
|
|
55
|
+
const m = await factory();
|
|
56
|
+
// Fail loudly on a stale or truncated dist: a module missing the
|
|
57
|
+
// engine's exports would otherwise answer every call with empty
|
|
58
|
+
// strings and consumed bytes at microsecond speed (yeptris-ts#4 —
|
|
59
|
+
// the published 0.1.0 measured 121k loads/s on 205 KB, i.e. no
|
|
60
|
+
// parse at all).
|
|
61
|
+
for (const fn of [
|
|
62
|
+
"_yeptris_wasm_load",
|
|
63
|
+
"_yeptris_wasm_dump",
|
|
64
|
+
"_yeptris_wasm_out",
|
|
65
|
+
"_yeptris_wasm_out_len",
|
|
66
|
+
"_yeptris_wasm_out_free",
|
|
67
|
+
"_yeptris_wasm_last_error",
|
|
68
|
+
"_yeptris_wasm_free",
|
|
69
|
+
"_malloc",
|
|
70
|
+
]) {
|
|
71
|
+
if (typeof m[fn] !== "function") {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`yeptris: dist/yeptris.mjs is missing the wasm export ${fn} — ` +
|
|
74
|
+
"rebuild with build.sh (stale or mismatched artifact)",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
cached = m;
|
|
79
|
+
return cached;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Parse YAML text and return the document as a JavaScript value
|
|
83
|
+
* (the engine's canonical JSON, JSON.parse'd). Throws YamlError with
|
|
84
|
+
* line/column on malformed input. */
|
|
85
|
+
export async function load(yaml) {
|
|
86
|
+
const m = await mod();
|
|
87
|
+
return JSON.parse(run(m, m._yeptris_wasm_load, yaml));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Parse YAML text and return the engine's canonical JSON string. */
|
|
91
|
+
export async function loadJSON(yaml) {
|
|
92
|
+
const m = await mod();
|
|
93
|
+
return run(m, m._yeptris_wasm_load, yaml);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Convert JSON text (or any JSON-serializable value) to the engine's
|
|
97
|
+
* canonical, byte-stable YAML. JSON is a subset of YAML 1.2 flow, so
|
|
98
|
+
* the one parse engine takes it. */
|
|
99
|
+
export async function dump(json) {
|
|
100
|
+
const m = await mod();
|
|
101
|
+
const text = typeof json === "string" ? json : JSON.stringify(json);
|
|
102
|
+
return run(m, m._yeptris_wasm_dump, text);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The libyeptris version string. */
|
|
106
|
+
export async function version() {
|
|
107
|
+
const m = await mod();
|
|
108
|
+
return m.UTF8ToString(m._yeptris_wasm_version());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** The wasm module instance this package caches (diagnostics:
|
|
112
|
+
* heap/memory inspection, the engine's raw exports). The load/dump
|
|
113
|
+
* calls all share this one instance. */
|
|
114
|
+
export async function wasmModule() {
|
|
115
|
+
return mod();
|
|
116
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* The wasm surface: one contained bridge over the zero-copy core.
|
|
2
|
+
* Input bytes are copied INTO the wasm heap; the document's views live
|
|
3
|
+
* inside the heap for the duration of the call; the answers (JSON from
|
|
4
|
+
* YAML, YAML from JSON) leave before the document is freed. The host
|
|
5
|
+
* never holds a heap pointer past the call — the C buffer-lifetime
|
|
6
|
+
* contract stays internal. */
|
|
7
|
+
#include <emscripten/emscripten.h>
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
|
|
12
|
+
#include "yeptris/dom.h"
|
|
13
|
+
#include "yeptris/emit.h"
|
|
14
|
+
#include "yeptris/error.h"
|
|
15
|
+
#include "yeptris/json.h"
|
|
16
|
+
#include "yeptris/parse.h"
|
|
17
|
+
#include "yeptris/version.h"
|
|
18
|
+
|
|
19
|
+
static char *g_out;
|
|
20
|
+
static size_t g_out_len;
|
|
21
|
+
|
|
22
|
+
static char last_error[256];
|
|
23
|
+
static int last_error_line;
|
|
24
|
+
static int last_error_column;
|
|
25
|
+
|
|
26
|
+
static void capture_error(void) {
|
|
27
|
+
uint32_t line = 0;
|
|
28
|
+
uint32_t col = 0;
|
|
29
|
+
const char *msg = yeptris_last_error(&line, &col);
|
|
30
|
+
snprintf(last_error, sizeof last_error, "%s", msg ? msg : "parse failed");
|
|
31
|
+
last_error_line = (int)line;
|
|
32
|
+
last_error_column = (int)col;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* YAML in -> canonical JSON out (yeptris_serialize_json). */
|
|
36
|
+
EMSCRIPTEN_KEEPALIVE
|
|
37
|
+
int yeptris_wasm_load(const char *data, size_t len) {
|
|
38
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
39
|
+
YeptrisDocument doc = yeptris_parse(data, len, &st);
|
|
40
|
+
if (doc == NULL || st != YEPTRIS_OK) {
|
|
41
|
+
capture_error();
|
|
42
|
+
return (int)st;
|
|
43
|
+
}
|
|
44
|
+
size_t out_len = 0;
|
|
45
|
+
char *out = yeptris_serialize_json(doc, &out_len);
|
|
46
|
+
yeptris_document_free(doc);
|
|
47
|
+
if (out == NULL) {
|
|
48
|
+
snprintf(last_error, sizeof last_error, "serialization failed");
|
|
49
|
+
last_error_line = 0;
|
|
50
|
+
last_error_column = 0;
|
|
51
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
52
|
+
}
|
|
53
|
+
g_out = out;
|
|
54
|
+
g_out_len = out_len;
|
|
55
|
+
return YEPTRIS_OK;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* JSON in -> canonical YAML out (JSON is a subset of YAML 1.2 flow, so
|
|
59
|
+
* the one parse engine takes it; the emitter's canonical form is
|
|
60
|
+
* byte-stable across round trips). */
|
|
61
|
+
EMSCRIPTEN_KEEPALIVE
|
|
62
|
+
int yeptris_wasm_dump(const char *data, size_t len) {
|
|
63
|
+
YeptrisStatus st = YEPTRIS_OK;
|
|
64
|
+
YeptrisDocument doc = yeptris_parse(data, len, &st);
|
|
65
|
+
if (doc == NULL || st != YEPTRIS_OK) {
|
|
66
|
+
capture_error();
|
|
67
|
+
return (int)st;
|
|
68
|
+
}
|
|
69
|
+
size_t out_len = 0;
|
|
70
|
+
char *out = yeptris_serialize(doc, &out_len);
|
|
71
|
+
yeptris_document_free(doc);
|
|
72
|
+
if (out == NULL) {
|
|
73
|
+
snprintf(last_error, sizeof last_error, "serialization failed");
|
|
74
|
+
last_error_line = 0;
|
|
75
|
+
last_error_column = 0;
|
|
76
|
+
return YEPTRIS_ERROR_MEMORY;
|
|
77
|
+
}
|
|
78
|
+
g_out = out;
|
|
79
|
+
g_out_len = out_len;
|
|
80
|
+
return YEPTRIS_OK;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
EMSCRIPTEN_KEEPALIVE
|
|
84
|
+
const char *yeptris_wasm_last_error(void) { return last_error; }
|
|
85
|
+
|
|
86
|
+
EMSCRIPTEN_KEEPALIVE
|
|
87
|
+
int yeptris_wasm_last_error_line(void) { return last_error_line; }
|
|
88
|
+
|
|
89
|
+
EMSCRIPTEN_KEEPALIVE
|
|
90
|
+
int yeptris_wasm_last_error_column(void) { return last_error_column; }
|
|
91
|
+
|
|
92
|
+
EMSCRIPTEN_KEEPALIVE
|
|
93
|
+
const char *yeptris_wasm_out(void) { return g_out; }
|
|
94
|
+
|
|
95
|
+
EMSCRIPTEN_KEEPALIVE
|
|
96
|
+
int yeptris_wasm_out_len(void) { return (int)g_out_len; }
|
|
97
|
+
|
|
98
|
+
EMSCRIPTEN_KEEPALIVE
|
|
99
|
+
void yeptris_wasm_out_free(void) {
|
|
100
|
+
yeptris_free(g_out);
|
|
101
|
+
g_out = NULL;
|
|
102
|
+
g_out_len = 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
EMSCRIPTEN_KEEPALIVE
|
|
106
|
+
void yeptris_wasm_free(void *p) { yeptris_free(p); }
|
|
107
|
+
|
|
108
|
+
EMSCRIPTEN_KEEPALIVE
|
|
109
|
+
const char *yeptris_wasm_version(void) { return yeptris_version(); }
|