teptris 0.3.3 → 0.3.5
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/dist/teptris.mjs +16 -2
- package/dist/teptris.wasm +0 -0
- package/package.json +5 -1
- package/src/index.d.ts +22 -0
- package/src/index.js +124 -2
- package/src/teptris_wasm.c +421 -0
package/dist/teptris.mjs
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
async function Module(moduleArg={}){var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(ENVIRONMENT_IS_NODE){const{createRequire}=await import("node:module");var require=createRequire(import.meta.url)}var programArgs=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=import.meta.url;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");if(_scriptName.startsWith("file:")){scriptDirectory=require("node:path").dirname(require("node:url").fileURLToPath(_scriptName))+"/"}readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}programArgs=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var runtimeInitialized=false;function getMemoryBuffer(){return wasmMemory.buffer}function updateMemoryViews(){if(HEAP8?.buffer?.resizable)return;var b=getMemoryBuffer();HEAP8=new Int8Array(b);HEAPU8=new Uint8Array(b)}function preRun(){var preRun=Module["preRun"];if(preRun){if(typeof preRun=="function")preRun=[preRun];onPreRuns.push(...preRun)}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["d"]()}function postRun(){var postRun=Module["postRun"];if(postRun){if(typeof postRun=="function")postRun=[postRun];onPostRuns.push(...postRun)}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){if(Module["locateFile"]){return locateFile("teptris.wasm")}return new URL("teptris.wasm",import.meta.url).href}function getBinarySync(file){if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();var instantiateWasm=Module["instantiateWasm"];if(instantiateWasm){return new Promise(resolve=>{instantiateWasm(info,inst=>resolve(receiveInstance(inst)))})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var HEAP8;var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var onPreRuns=[];var noExitRuntime=true;var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);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 HEAPU8;var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;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}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,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};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.codePointAt(i);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;i++}}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};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var preInit=Module["preInit"];if(preInit){if(typeof preInit=="function")Module["preInit"]=preInit=[preInit];while(preInit.length>0){preInit.shift()()}}}Module["UTF8ToString"]=UTF8ToString;Module["stringToUTF8"]=stringToUTF8;Module["lengthBytesUTF8"]=lengthBytesUTF8;var _teptris_wasm_load,_teptris_wasm_last_error,_teptris_wasm_last_error_line,_teptris_wasm_last_error_column,_teptris_wasm_json,_teptris_wasm_json_len,_teptris_wasm_free,_teptris_wasm_builder_new,_teptris_wasm_builder_free,_teptris_wasm_builder_put_string,_teptris_wasm_builder_put_integer,_teptris_wasm_builder_put_float,_teptris_wasm_builder_put_boolean,_teptris_wasm_builder_put_datetime,_teptris_wasm_builder_open_table,_teptris_wasm_builder_open_array,_teptris_wasm_builder_close,_teptris_wasm_builder_finish,_teptris_wasm_builder_finish_json_natural,_teptris_wasm_toml,_teptris_wasm_toml_len,_malloc,_teptris_version_string,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_teptris_wasm_load=Module["_teptris_wasm_load"]=wasmExports["e"];_teptris_wasm_last_error=Module["_teptris_wasm_last_error"]=wasmExports["f"];_teptris_wasm_last_error_line=Module["_teptris_wasm_last_error_line"]=wasmExports["g"];_teptris_wasm_last_error_column=Module["_teptris_wasm_last_error_column"]=wasmExports["h"];_teptris_wasm_json=Module["_teptris_wasm_json"]=wasmExports["i"];_teptris_wasm_json_len=Module["_teptris_wasm_json_len"]=wasmExports["j"];_teptris_wasm_free=Module["_teptris_wasm_free"]=wasmExports["k"];_teptris_wasm_builder_new=Module["_teptris_wasm_builder_new"]=wasmExports["l"];_teptris_wasm_builder_free=Module["_teptris_wasm_builder_free"]=wasmExports["m"];_teptris_wasm_builder_put_string=Module["_teptris_wasm_builder_put_string"]=wasmExports["n"];_teptris_wasm_builder_put_integer=Module["_teptris_wasm_builder_put_integer"]=wasmExports["o"];_teptris_wasm_builder_put_float=Module["_teptris_wasm_builder_put_float"]=wasmExports["p"];_teptris_wasm_builder_put_boolean=Module["_teptris_wasm_builder_put_boolean"]=wasmExports["q"];_teptris_wasm_builder_put_datetime=Module["_teptris_wasm_builder_put_datetime"]=wasmExports["r"];_teptris_wasm_builder_open_table=Module["_teptris_wasm_builder_open_table"]=wasmExports["s"];_teptris_wasm_builder_open_array=Module["_teptris_wasm_builder_open_array"]=wasmExports["t"];_teptris_wasm_builder_close=Module["_teptris_wasm_builder_close"]=wasmExports["u"];_teptris_wasm_builder_finish=Module["_teptris_wasm_builder_finish"]=wasmExports["v"];_teptris_wasm_builder_finish_json_natural=Module["_teptris_wasm_builder_finish_json_natural"]=wasmExports["w"];_teptris_wasm_toml=Module["_teptris_wasm_toml"]=wasmExports["x"];_teptris_wasm_toml_len=Module["_teptris_wasm_toml_len"]=wasmExports["y"];_malloc=Module["_malloc"]=wasmExports["z"];_teptris_version_string=Module["_teptris_version_string"]=wasmExports["A"];memory=wasmMemory=wasmExports["c"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={a:___assert_fail,b:_emscripten_resize_heap};async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}var wasmExports;wasmExports=await createWasm();await run();
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
var Module = (() => {
|
|
3
|
+
var _scriptName = import.meta.url;
|
|
4
|
+
|
|
5
|
+
return (
|
|
6
|
+
async function(moduleArg = {}) {
|
|
7
|
+
var moduleRtn;
|
|
8
|
+
|
|
9
|
+
var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";if(ENVIRONMENT_IS_NODE){const{createRequire}=await import("module");let dirname=import.meta.url;if(dirname.startsWith("data:")){dirname="/"}var require=createRequire(dirname)}var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");if(!import.meta.url.startsWith("data:")){scriptDirectory=nodePath.dirname(require("url").fileURLToPath(import.meta.url))+"/"}readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};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}}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(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}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"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;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 dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;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://");function findWasmBinary(){if(Module["locateFile"]){var f="teptris.wasm";if(!isDataURI(f)){return locateFile(f)}return f}return new URL("teptris.wasm",import.meta.url).href}var wasmBinaryFile;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"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["c"];updateMemoryViews();addOnInit(wasmExports["d"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}wasmBinaryFile??=findWasmBinary();try{var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);receiveInstantiationResult(result);return result}catch(e){readyPromiseReject(e);return}}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var noExitRuntime=Module["noExitRuntime"]||true;var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{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 ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536|0;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}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,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};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={a:___assert_fail,b:_emscripten_resize_heap};var wasmExports;createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["d"])();var _teptris_wasm_load=Module["_teptris_wasm_load"]=(a0,a1)=>(_teptris_wasm_load=Module["_teptris_wasm_load"]=wasmExports["e"])(a0,a1);var _teptris_wasm_last_error=Module["_teptris_wasm_last_error"]=()=>(_teptris_wasm_last_error=Module["_teptris_wasm_last_error"]=wasmExports["f"])();var _teptris_wasm_last_error_line=Module["_teptris_wasm_last_error_line"]=()=>(_teptris_wasm_last_error_line=Module["_teptris_wasm_last_error_line"]=wasmExports["g"])();var _teptris_wasm_last_error_column=Module["_teptris_wasm_last_error_column"]=()=>(_teptris_wasm_last_error_column=Module["_teptris_wasm_last_error_column"]=wasmExports["h"])();var _teptris_wasm_json=Module["_teptris_wasm_json"]=()=>(_teptris_wasm_json=Module["_teptris_wasm_json"]=wasmExports["i"])();var _teptris_wasm_json_len=Module["_teptris_wasm_json_len"]=()=>(_teptris_wasm_json_len=Module["_teptris_wasm_json_len"]=wasmExports["j"])();var _teptris_wasm_free=Module["_teptris_wasm_free"]=a0=>(_teptris_wasm_free=Module["_teptris_wasm_free"]=wasmExports["k"])(a0);var _teptris_wasm_alloc=Module["_teptris_wasm_alloc"]=a0=>(_teptris_wasm_alloc=Module["_teptris_wasm_alloc"]=wasmExports["l"])(a0);var _teptris_wasm_builder_new=Module["_teptris_wasm_builder_new"]=()=>(_teptris_wasm_builder_new=Module["_teptris_wasm_builder_new"]=wasmExports["m"])();var _teptris_wasm_builder_free=Module["_teptris_wasm_builder_free"]=a0=>(_teptris_wasm_builder_free=Module["_teptris_wasm_builder_free"]=wasmExports["n"])(a0);var _teptris_wasm_builder_put_string=Module["_teptris_wasm_builder_put_string"]=(a0,a1,a2)=>(_teptris_wasm_builder_put_string=Module["_teptris_wasm_builder_put_string"]=wasmExports["o"])(a0,a1,a2);var _teptris_wasm_builder_put_integer=Module["_teptris_wasm_builder_put_integer"]=(a0,a1,a2)=>(_teptris_wasm_builder_put_integer=Module["_teptris_wasm_builder_put_integer"]=wasmExports["p"])(a0,a1,a2);var _teptris_wasm_builder_put_float=Module["_teptris_wasm_builder_put_float"]=(a0,a1,a2)=>(_teptris_wasm_builder_put_float=Module["_teptris_wasm_builder_put_float"]=wasmExports["q"])(a0,a1,a2);var _teptris_wasm_builder_put_boolean=Module["_teptris_wasm_builder_put_boolean"]=(a0,a1,a2)=>(_teptris_wasm_builder_put_boolean=Module["_teptris_wasm_builder_put_boolean"]=wasmExports["r"])(a0,a1,a2);var _teptris_wasm_builder_put_datetime=Module["_teptris_wasm_builder_put_datetime"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)=>(_teptris_wasm_builder_put_datetime=Module["_teptris_wasm_builder_put_datetime"]=wasmExports["s"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);var _teptris_wasm_builder_open_table=Module["_teptris_wasm_builder_open_table"]=(a0,a1)=>(_teptris_wasm_builder_open_table=Module["_teptris_wasm_builder_open_table"]=wasmExports["t"])(a0,a1);var _teptris_wasm_builder_open_array=Module["_teptris_wasm_builder_open_array"]=(a0,a1)=>(_teptris_wasm_builder_open_array=Module["_teptris_wasm_builder_open_array"]=wasmExports["u"])(a0,a1);var _teptris_wasm_builder_close=Module["_teptris_wasm_builder_close"]=a0=>(_teptris_wasm_builder_close=Module["_teptris_wasm_builder_close"]=wasmExports["v"])(a0);var _teptris_wasm_builder_finish=Module["_teptris_wasm_builder_finish"]=a0=>(_teptris_wasm_builder_finish=Module["_teptris_wasm_builder_finish"]=wasmExports["w"])(a0);var _teptris_wasm_builder_finish_json_natural=Module["_teptris_wasm_builder_finish_json_natural"]=a0=>(_teptris_wasm_builder_finish_json_natural=Module["_teptris_wasm_builder_finish_json_natural"]=wasmExports["x"])(a0);var _teptris_wasm_toml=Module["_teptris_wasm_toml"]=()=>(_teptris_wasm_toml=Module["_teptris_wasm_toml"]=wasmExports["y"])();var _teptris_wasm_toml_len=Module["_teptris_wasm_toml_len"]=()=>(_teptris_wasm_toml_len=Module["_teptris_wasm_toml_len"]=wasmExports["z"])();var _teptris_wasm_plan_build=Module["_teptris_wasm_plan_build"]=(a0,a1,a2,a3,a4,a5)=>(_teptris_wasm_plan_build=Module["_teptris_wasm_plan_build"]=wasmExports["A"])(a0,a1,a2,a3,a4,a5);var _teptris_wasm_plan_free=Module["_teptris_wasm_plan_free"]=a0=>(_teptris_wasm_plan_free=Module["_teptris_wasm_plan_free"]=wasmExports["B"])(a0);var _teptris_wasm_poke_u32=Module["_teptris_wasm_poke_u32"]=(a0,a1,a2)=>(_teptris_wasm_poke_u32=Module["_teptris_wasm_poke_u32"]=wasmExports["C"])(a0,a1,a2);var _teptris_wasm_poke_u8=Module["_teptris_wasm_poke_u8"]=(a0,a1,a2)=>(_teptris_wasm_poke_u8=Module["_teptris_wasm_poke_u8"]=wasmExports["D"])(a0,a1,a2);var _teptris_wasm_plan_walk=Module["_teptris_wasm_plan_walk"]=(a0,a1,a2)=>(_teptris_wasm_plan_walk=Module["_teptris_wasm_plan_walk"]=wasmExports["E"])(a0,a1,a2);var _teptris_version_string=Module["_teptris_version_string"]=()=>(_teptris_version_string=Module["_teptris_version_string"]=wasmExports["G"])();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);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>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();moduleRtn=readyPromise;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
return moduleRtn;
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
})();
|
|
16
|
+
export default Module;
|
package/dist/teptris.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teptris",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "TOML for JavaScript/TypeScript at libteptris speed (WebAssembly, no fallback) - version tracks the engine ({engine}.{iteration}; npm semver is 3-part)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"test": "node --test test/test.mjs test/package.test.mjs"
|
|
20
20
|
},
|
|
21
21
|
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/leptris/teptris-ts.git"
|
|
25
|
+
},
|
|
22
26
|
"engines": {
|
|
23
27
|
"node": ">=20"
|
|
24
28
|
},
|
package/src/index.d.ts
CHANGED
|
@@ -47,6 +47,28 @@ export interface TeptrisApi {
|
|
|
47
47
|
|
|
48
48
|
/** The libteptris engine version inside this build. */
|
|
49
49
|
engineVersion(): string;
|
|
50
|
+
|
|
51
|
+
/** Compile a descriptor plan (once) — materialize only the planned
|
|
52
|
+
* keys of any document via planWalk. Rows: a string name is a
|
|
53
|
+
* scalar; kind "collection" walks an array; kind "raw" takes the
|
|
54
|
+
* untouched subtree; rows: [...] walks a nested table. */
|
|
55
|
+
planBuild(rows: PlanRowSpec[]): number;
|
|
56
|
+
|
|
57
|
+
/** Walk one TOML document against the plan; returns only the
|
|
58
|
+
* planned keys (natural shapes: RFC 3339 datetime strings,
|
|
59
|
+
* non-finite floats as null). Throws on parse/plan errors. */
|
|
60
|
+
planWalk(plan: number, toml: string): TomlTable;
|
|
61
|
+
|
|
62
|
+
/** Release a compiled plan. */
|
|
63
|
+
planFree(plan: number): void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** One planned key of a {@link PlanRowSpec} tree. */
|
|
67
|
+
export interface PlanRowSpec {
|
|
68
|
+
name: string;
|
|
69
|
+
kind?: "scalar" | "collection" | "raw";
|
|
70
|
+
/** Nested table rows — makes this row a nested table. */
|
|
71
|
+
rows?: PlanRowSpec[];
|
|
50
72
|
}
|
|
51
73
|
|
|
52
74
|
/** Instantiate the WebAssembly engine and return the API. */
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const KIND_OFFSET = 4, KIND_LOCAL_DT = 5, KIND_DATE = 6, KIND_TIME = 7;
|
|
|
5
5
|
|
|
6
6
|
function cstr(mod, s) {
|
|
7
7
|
const bytes = mod.lengthBytesUTF8(s) + 1;
|
|
8
|
-
const ptr = mod.
|
|
8
|
+
const ptr = mod._teptris_wasm_alloc(bytes);
|
|
9
9
|
mod.stringToUTF8(s, ptr, bytes);
|
|
10
10
|
return ptr;
|
|
11
11
|
}
|
|
@@ -199,7 +199,129 @@ export function initApi(mod) {
|
|
|
199
199
|
return UTF8ToString(mod._teptris_version_string());
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
|
|
202
|
+
// ---- descriptor plans: compile once, materialize only planned keys
|
|
203
|
+
|
|
204
|
+
function planError() {
|
|
205
|
+
const e = new Error(UTF8ToString(mod._teptris_wasm_last_error()));
|
|
206
|
+
e.line = mod._teptris_wasm_last_error_line();
|
|
207
|
+
e.column = mod._teptris_wasm_last_error_column();
|
|
208
|
+
return e;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// rows: "name" (scalar) | { name, kind: "collection" | "raw" } |
|
|
212
|
+
// { name, rows: [...] } (nested). Returns an opaque plan handle.
|
|
213
|
+
function planBuild(rows) {
|
|
214
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
215
|
+
throw new TypeError("planBuild expects a non-empty array of rows");
|
|
216
|
+
}
|
|
217
|
+
const flat = []; // { np, kind, sub }
|
|
218
|
+
const first = [0];
|
|
219
|
+
const namePtrs = [];
|
|
220
|
+
const pending = []; // [flatSlot, children]
|
|
221
|
+
for (const r of rows) {
|
|
222
|
+
const name = typeof r === "string" ? r : r.name;
|
|
223
|
+
let kind = 1; // scalar
|
|
224
|
+
if (typeof r === "object" && Array.isArray(r.rows)) {
|
|
225
|
+
kind = 3; // nested — sub patched after the child block
|
|
226
|
+
const slot = flat.length;
|
|
227
|
+
const np = mod._teptris_wasm_alloc(name.length + 1);
|
|
228
|
+
stringToUTF8(name, np, name.length + 1);
|
|
229
|
+
namePtrs.push(np);
|
|
230
|
+
flat.push({ np, kind, sub: 0 });
|
|
231
|
+
pending.push([slot, r.rows]);
|
|
232
|
+
} else {
|
|
233
|
+
if (typeof r === "object" && r.kind === "collection") kind = 2;
|
|
234
|
+
else if (typeof r === "object" && r.kind === "raw") kind = 4;
|
|
235
|
+
const np = mod._teptris_wasm_alloc(name.length + 1);
|
|
236
|
+
stringToUTF8(name, np, name.length + 1);
|
|
237
|
+
namePtrs.push(np);
|
|
238
|
+
flat.push({ np, kind, sub: 0 });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// parent rows first; sub-plans laid out after them (first[] grows
|
|
242
|
+
// in plan order — the C layout contract). SIBLING nested rows must
|
|
243
|
+
// not capture the same index: patch sub after each child block.
|
|
244
|
+
for (const [slot, children] of pending) {
|
|
245
|
+
first.push(flat.length);
|
|
246
|
+
flattenInto(children, flat, first, namePtrs, pending);
|
|
247
|
+
flat[slot].sub = first.length - 1;
|
|
248
|
+
}
|
|
249
|
+
// the end sentinel for the last plan (first[] has plan_count+1
|
|
250
|
+
// entries — its absence made every sub index point past the end)
|
|
251
|
+
first.push(flat.length);
|
|
252
|
+
const namesBuf = mod._teptris_wasm_alloc(4 * flat.length);
|
|
253
|
+
const kindsBuf = mod._teptris_wasm_alloc(flat.length);
|
|
254
|
+
const subsBuf = mod._teptris_wasm_alloc(4 * flat.length);
|
|
255
|
+
const firstBuf = mod._teptris_wasm_alloc(4 * first.length);
|
|
256
|
+
flat.forEach((f, i) => {
|
|
257
|
+
mod._teptris_wasm_poke_u32(namesBuf, i, f.np);
|
|
258
|
+
mod._teptris_wasm_poke_u8(kindsBuf, i, f.kind);
|
|
259
|
+
mod._teptris_wasm_poke_u32(subsBuf, i, f.sub);
|
|
260
|
+
});
|
|
261
|
+
first.forEach((v, i) => mod._teptris_wasm_poke_u32(firstBuf, i, v));
|
|
262
|
+
const plan = mod._teptris_wasm_plan_build(
|
|
263
|
+
namesBuf, kindsBuf, subsBuf, flat.length, firstBuf, first.length);
|
|
264
|
+
namePtrs.forEach((np) => mod._teptris_wasm_free(np));
|
|
265
|
+
mod._teptris_wasm_free(namesBuf);
|
|
266
|
+
mod._teptris_wasm_free(kindsBuf);
|
|
267
|
+
mod._teptris_wasm_free(subsBuf);
|
|
268
|
+
mod._teptris_wasm_free(firstBuf);
|
|
269
|
+
if (!plan) {
|
|
270
|
+
throw planError();
|
|
271
|
+
}
|
|
272
|
+
return plan;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function flattenInto(rows, flat, first, namePtrs, pending) {
|
|
276
|
+
const slots = []; // [flatSlot, children]
|
|
277
|
+
for (const r of rows) {
|
|
278
|
+
const name = typeof r === "string" ? r : r.name;
|
|
279
|
+
let kind = 1;
|
|
280
|
+
if (typeof r === "object" && Array.isArray(r.rows)) {
|
|
281
|
+
kind = 3;
|
|
282
|
+
const slot = flat.length;
|
|
283
|
+
const np = mod._teptris_wasm_alloc(name.length + 1);
|
|
284
|
+
stringToUTF8(name, np, name.length + 1);
|
|
285
|
+
namePtrs.push(np);
|
|
286
|
+
flat.push({ np, kind, sub: 0 });
|
|
287
|
+
slots.push([slot, r.rows]);
|
|
288
|
+
} else {
|
|
289
|
+
if (typeof r === "object" && r.kind === "collection") kind = 2;
|
|
290
|
+
else if (typeof r === "object" && r.kind === "raw") kind = 4;
|
|
291
|
+
const np = mod._teptris_wasm_alloc(name.length + 1);
|
|
292
|
+
stringToUTF8(name, np, name.length + 1);
|
|
293
|
+
namePtrs.push(np);
|
|
294
|
+
flat.push({ np, kind, sub: 0 });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
for (const [slot, children] of slots) {
|
|
298
|
+
first.push(flat.length);
|
|
299
|
+
flattenInto(children, flat, first, namePtrs, pending);
|
|
300
|
+
flat[slot].sub = first.length - 1;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function planWalk(plan, toml) {
|
|
305
|
+
if (typeof toml !== "string") {
|
|
306
|
+
throw new TypeError("planWalk expects a TOML string");
|
|
307
|
+
}
|
|
308
|
+
const p = cstr(mod, toml);
|
|
309
|
+
const st = mod._teptris_wasm_plan_walk(plan, p, lengthBytesUTF8(toml));
|
|
310
|
+
freeCstr(mod, p);
|
|
311
|
+
if (st !== 0) {
|
|
312
|
+
throw planError();
|
|
313
|
+
}
|
|
314
|
+
const jptr = mod._teptris_wasm_json();
|
|
315
|
+
const value = JSON.parse(UTF8ToString(jptr));
|
|
316
|
+
mod._teptris_wasm_free(jptr);
|
|
317
|
+
return value;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function planFree(plan) {
|
|
321
|
+
mod._teptris_wasm_plan_free(plan);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return { loads, dump, dumpJson, planBuild, planWalk, planFree, engineVersion };
|
|
203
325
|
}
|
|
204
326
|
|
|
205
327
|
// The consumer entry: instantiate the engine once, get the API.
|
package/src/teptris_wasm.c
CHANGED
|
@@ -59,6 +59,12 @@ int teptris_wasm_json_len(void) { return (int)g_json_len; }
|
|
|
59
59
|
EMSCRIPTEN_KEEPALIVE
|
|
60
60
|
void teptris_wasm_free(void *p) { free(p); }
|
|
61
61
|
|
|
62
|
+
/* JS-side allocations MUST go through the same allocator as free()
|
|
63
|
+
* above: force-exporting _malloc alongside ASAN's own malloc/free
|
|
64
|
+
* splits the heap across two allocators and every free misreports. */
|
|
65
|
+
EMSCRIPTEN_KEEPALIVE
|
|
66
|
+
void *teptris_wasm_alloc(size_t n) { return malloc(n); }
|
|
67
|
+
|
|
62
68
|
/* ---- builder surface (the dump side) ----------------------------- *
|
|
63
69
|
* 1:1 with teptris_builder_*: the JS wrapper drives the same stack
|
|
64
70
|
* discipline (open/close, NULL key = array element) the C and Rust
|
|
@@ -163,3 +169,418 @@ const char *teptris_wasm_toml(void) { return g_toml; }
|
|
|
163
169
|
|
|
164
170
|
EMSCRIPTEN_KEEPALIVE
|
|
165
171
|
int teptris_wasm_toml_len(void) { return (int)g_toml_len; }
|
|
172
|
+
|
|
173
|
+
/* ------------------------------------------------ descriptor plans -- *
|
|
174
|
+
* Plan an once, walk many documents: only the planned keys are
|
|
175
|
+
* materialized (the engine plan API). The JS side flattens the plan
|
|
176
|
+
* tree honoring plan p's contiguous range [first[p], first[p+1]) and
|
|
177
|
+
* passes parallel arrays; materialization goes through the builder so
|
|
178
|
+
* the emitter stays the single formatting truth, and RAW rows re-use
|
|
179
|
+
* the plain node accessors. */
|
|
180
|
+
|
|
181
|
+
#include "teptris/plan.h"
|
|
182
|
+
|
|
183
|
+
EMSCRIPTEN_KEEPALIVE
|
|
184
|
+
void *teptris_wasm_plan_build(const char **names, const uint8_t *kinds,
|
|
185
|
+
const uint32_t *subs, uint32_t nrows,
|
|
186
|
+
const uint32_t *first, uint32_t nfirst) {
|
|
187
|
+
if (nrows == 0 || nfirst < 2) {
|
|
188
|
+
snprintf(last_error, sizeof last_error, "plan needs rows");
|
|
189
|
+
return NULL;
|
|
190
|
+
}
|
|
191
|
+
teptris_plan_row *rows = malloc(nrows * sizeof *rows);
|
|
192
|
+
if (rows == NULL) {
|
|
193
|
+
return NULL;
|
|
194
|
+
}
|
|
195
|
+
for (uint32_t i = 0; i < nrows; i++) {
|
|
196
|
+
rows[i].name = names[i];
|
|
197
|
+
rows[i].kind = kinds[i];
|
|
198
|
+
rows[i].sub = subs[i];
|
|
199
|
+
}
|
|
200
|
+
teptris_plan_spec spec;
|
|
201
|
+
spec.abi_version = TEPTRIS_PLAN_ABI_VERSION;
|
|
202
|
+
spec.plan_count = nfirst - 1;
|
|
203
|
+
spec.plans = rows;
|
|
204
|
+
spec.plan_first_row = first;
|
|
205
|
+
teptris_status st;
|
|
206
|
+
teptris_plan *p = teptris_plan_build(&spec, &st);
|
|
207
|
+
free(rows);
|
|
208
|
+
if (st != TEPTRIS_OK) {
|
|
209
|
+
snprintf(last_error, sizeof last_error, "plan build failed (%s)",
|
|
210
|
+
teptris_status_string(st));
|
|
211
|
+
return NULL;
|
|
212
|
+
}
|
|
213
|
+
return p;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
EMSCRIPTEN_KEEPALIVE
|
|
217
|
+
void teptris_wasm_plan_free(teptris_plan *plan) { teptris_plan_free(plan); }
|
|
218
|
+
|
|
219
|
+
/* JS cannot write typed memory without heap views (which detach on
|
|
220
|
+
* memory growth) — two trivial pokes keep plan-spec assembly on the
|
|
221
|
+
* C side of the line. */
|
|
222
|
+
EMSCRIPTEN_KEEPALIVE
|
|
223
|
+
void teptris_wasm_poke_u32(uint32_t *p, uint32_t i, uint32_t v) {
|
|
224
|
+
p[i] = v;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
EMSCRIPTEN_KEEPALIVE
|
|
228
|
+
void teptris_wasm_poke_u8(uint8_t *p, uint32_t i, uint8_t v) {
|
|
229
|
+
p[i] = v;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
static int put_scalar_result(teptris_builder *b, const char *key,
|
|
233
|
+
const teptris_plan_result *res, uint32_t i) {
|
|
234
|
+
teptris_datetime dt;
|
|
235
|
+
switch (teptris_plan_result_value_kind_at(res, i)) {
|
|
236
|
+
case TEPTRIS_STRING: {
|
|
237
|
+
teptris_view v;
|
|
238
|
+
if (teptris_plan_result_string_at(res, i, &v) != TEPTRIS_OK) {
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
return teptris_builder_put_string(b, key, strlen(key), v.ptr, v.len)
|
|
242
|
+
!= TEPTRIS_OK;
|
|
243
|
+
}
|
|
244
|
+
case TEPTRIS_INTEGER: {
|
|
245
|
+
int64_t iv;
|
|
246
|
+
if (teptris_plan_result_integer_at(res, i, &iv) != TEPTRIS_OK) {
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
return teptris_builder_put_integer(b, key, strlen(key), iv)
|
|
250
|
+
!= TEPTRIS_OK;
|
|
251
|
+
}
|
|
252
|
+
case TEPTRIS_FLOAT: {
|
|
253
|
+
double dv;
|
|
254
|
+
if (teptris_plan_result_float_at(res, i, &dv) != TEPTRIS_OK) {
|
|
255
|
+
return 1;
|
|
256
|
+
}
|
|
257
|
+
return teptris_builder_put_float(b, key, strlen(key), dv) != TEPTRIS_OK;
|
|
258
|
+
}
|
|
259
|
+
case TEPTRIS_BOOLEAN: {
|
|
260
|
+
bool bv;
|
|
261
|
+
if (teptris_plan_result_boolean_at(res, i, &bv) != TEPTRIS_OK) {
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
return teptris_builder_put_boolean(b, key, strlen(key), bv)
|
|
265
|
+
!= TEPTRIS_OK;
|
|
266
|
+
}
|
|
267
|
+
case TEPTRIS_DATETIME_OFFSET:
|
|
268
|
+
case TEPTRIS_DATETIME_LOCAL:
|
|
269
|
+
case TEPTRIS_DATE_LOCAL:
|
|
270
|
+
case TEPTRIS_TIME_LOCAL:
|
|
271
|
+
if (teptris_plan_result_datetime_at(res, i, &dt) != TEPTRIS_OK) {
|
|
272
|
+
return 1;
|
|
273
|
+
}
|
|
274
|
+
return teptris_builder_put_datetime(b, key, strlen(key),
|
|
275
|
+
(teptris_kind)teptris_plan_result_value_kind_at(
|
|
276
|
+
res, i),
|
|
277
|
+
&dt)
|
|
278
|
+
!= TEPTRIS_OK;
|
|
279
|
+
default:
|
|
280
|
+
return 1;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
static int put_array_scalar_result(teptris_builder *b,
|
|
285
|
+
const teptris_plan_result *res, uint32_t i,
|
|
286
|
+
uint32_t j) {
|
|
287
|
+
teptris_datetime dt;
|
|
288
|
+
switch (teptris_plan_result_array_value_kind_at(res, i, j)) {
|
|
289
|
+
case TEPTRIS_STRING: {
|
|
290
|
+
teptris_view v;
|
|
291
|
+
if (teptris_plan_result_array_string_at(res, i, j, &v) != TEPTRIS_OK) {
|
|
292
|
+
return 1;
|
|
293
|
+
}
|
|
294
|
+
return teptris_builder_put_string(b, NULL, 0, v.ptr, v.len)
|
|
295
|
+
!= TEPTRIS_OK;
|
|
296
|
+
}
|
|
297
|
+
case TEPTRIS_INTEGER: {
|
|
298
|
+
int64_t iv;
|
|
299
|
+
if (teptris_plan_result_array_integer_at(res, i, j, &iv)
|
|
300
|
+
!= TEPTRIS_OK) {
|
|
301
|
+
return 1;
|
|
302
|
+
}
|
|
303
|
+
return teptris_builder_put_integer(b, NULL, 0, iv) != TEPTRIS_OK;
|
|
304
|
+
}
|
|
305
|
+
case TEPTRIS_FLOAT: {
|
|
306
|
+
double dv;
|
|
307
|
+
if (teptris_plan_result_array_float_at(res, i, j, &dv) != TEPTRIS_OK) {
|
|
308
|
+
return 1;
|
|
309
|
+
}
|
|
310
|
+
return teptris_builder_put_float(b, NULL, 0, dv) != TEPTRIS_OK;
|
|
311
|
+
}
|
|
312
|
+
case TEPTRIS_BOOLEAN: {
|
|
313
|
+
bool bv;
|
|
314
|
+
if (teptris_plan_result_array_boolean_at(res, i, j, &bv)
|
|
315
|
+
!= TEPTRIS_OK) {
|
|
316
|
+
return 1;
|
|
317
|
+
}
|
|
318
|
+
return teptris_builder_put_boolean(b, NULL, 0, bv) != TEPTRIS_OK;
|
|
319
|
+
}
|
|
320
|
+
case TEPTRIS_DATETIME_OFFSET:
|
|
321
|
+
case TEPTRIS_DATETIME_LOCAL:
|
|
322
|
+
case TEPTRIS_DATE_LOCAL:
|
|
323
|
+
case TEPTRIS_TIME_LOCAL:
|
|
324
|
+
if (teptris_plan_result_array_datetime_at(res, i, j, &dt)
|
|
325
|
+
!= TEPTRIS_OK) {
|
|
326
|
+
return 1;
|
|
327
|
+
}
|
|
328
|
+
return teptris_builder_put_datetime(b, NULL, 0,
|
|
329
|
+
(teptris_kind)teptris_plan_result_array_value_kind_at(
|
|
330
|
+
res, i, j),
|
|
331
|
+
&dt)
|
|
332
|
+
!= TEPTRIS_OK;
|
|
333
|
+
default:
|
|
334
|
+
return 1;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
static int put_node(teptris_builder *b, const char *key, size_t klen,
|
|
339
|
+
const teptris_node *n);
|
|
340
|
+
|
|
341
|
+
static int put_node_array(teptris_builder *b, const char *key,
|
|
342
|
+
const teptris_node *n) {
|
|
343
|
+
if (teptris_builder_open_array(b, key, key ? strlen(key) : 0)
|
|
344
|
+
!= TEPTRIS_OK) {
|
|
345
|
+
snprintf(last_error, sizeof last_error,
|
|
346
|
+
"plan asm: open_array failed");
|
|
347
|
+
return 1;
|
|
348
|
+
}
|
|
349
|
+
size_t n2 = teptris_node_array_length(n);
|
|
350
|
+
for (size_t j = 0; j < n2; j++) {
|
|
351
|
+
if (put_node(b, NULL, 0, teptris_node_array_at(n, j)) != 0) {
|
|
352
|
+
snprintf(last_error, sizeof last_error,
|
|
353
|
+
"plan asm: array elem %zu put_node failed", (size_t)j);
|
|
354
|
+
return 1;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (teptris_builder_close(b) != TEPTRIS_OK) {
|
|
358
|
+
snprintf(last_error, sizeof last_error,
|
|
359
|
+
"plan asm: close array failed");
|
|
360
|
+
return 1;
|
|
361
|
+
}
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static int put_node(teptris_builder *b, const char *key, size_t klen,
|
|
366
|
+
const teptris_node *n) {
|
|
367
|
+
teptris_view v;
|
|
368
|
+
int64_t iv;
|
|
369
|
+
double dv;
|
|
370
|
+
bool bv;
|
|
371
|
+
teptris_datetime dt;
|
|
372
|
+
switch (teptris_node_kind(n)) {
|
|
373
|
+
case TEPTRIS_STRING:
|
|
374
|
+
if (teptris_node_string(n, &v) != TEPTRIS_OK) {
|
|
375
|
+
return 1;
|
|
376
|
+
}
|
|
377
|
+
return teptris_builder_put_string(b, key, klen, v.ptr, v.len)
|
|
378
|
+
!= TEPTRIS_OK;
|
|
379
|
+
case TEPTRIS_INTEGER:
|
|
380
|
+
if (teptris_node_integer(n, &iv) != TEPTRIS_OK) {
|
|
381
|
+
return 1;
|
|
382
|
+
}
|
|
383
|
+
return teptris_builder_put_integer(b, key, klen, iv) != TEPTRIS_OK;
|
|
384
|
+
case TEPTRIS_FLOAT:
|
|
385
|
+
if (teptris_node_float(n, &dv) != TEPTRIS_OK) {
|
|
386
|
+
return 1;
|
|
387
|
+
}
|
|
388
|
+
return teptris_builder_put_float(b, key, klen, dv) != TEPTRIS_OK;
|
|
389
|
+
case TEPTRIS_BOOLEAN:
|
|
390
|
+
if (teptris_node_boolean(n, &bv) != TEPTRIS_OK) {
|
|
391
|
+
return 1;
|
|
392
|
+
}
|
|
393
|
+
return teptris_builder_put_boolean(b, key, klen, bv ? 1 : 0)
|
|
394
|
+
!= TEPTRIS_OK;
|
|
395
|
+
case TEPTRIS_DATETIME_OFFSET:
|
|
396
|
+
case TEPTRIS_DATETIME_LOCAL:
|
|
397
|
+
case TEPTRIS_DATE_LOCAL:
|
|
398
|
+
case TEPTRIS_TIME_LOCAL:
|
|
399
|
+
if (teptris_node_datetime(n, &dt) != TEPTRIS_OK) {
|
|
400
|
+
return 1;
|
|
401
|
+
}
|
|
402
|
+
return teptris_builder_put_datetime(b, key, klen,
|
|
403
|
+
teptris_node_kind(n), &dt)
|
|
404
|
+
!= TEPTRIS_OK;
|
|
405
|
+
case TEPTRIS_TABLE: {
|
|
406
|
+
if (teptris_builder_open_table(b, key, klen) != TEPTRIS_OK) {
|
|
407
|
+
snprintf(last_error, sizeof last_error,
|
|
408
|
+
"plan asm: open_table failed (klen %zu)", klen);
|
|
409
|
+
return 1;
|
|
410
|
+
}
|
|
411
|
+
size_t n2 = teptris_node_table_length(n);
|
|
412
|
+
for (size_t j = 0; j < n2; j++) {
|
|
413
|
+
teptris_view child_key;
|
|
414
|
+
const teptris_node *child =
|
|
415
|
+
teptris_node_table_at(n, j, &child_key);
|
|
416
|
+
if (child != NULL
|
|
417
|
+
&& put_node(b, child_key.ptr, child_key.len, child) != 0) {
|
|
418
|
+
snprintf(last_error, sizeof last_error,
|
|
419
|
+
"plan asm: table child %zu put_node failed",
|
|
420
|
+
(size_t)j);
|
|
421
|
+
return 1;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (teptris_builder_close(b) != TEPTRIS_OK) {
|
|
425
|
+
snprintf(last_error, sizeof last_error,
|
|
426
|
+
"plan asm: close table failed");
|
|
427
|
+
return 1;
|
|
428
|
+
}
|
|
429
|
+
return 0;
|
|
430
|
+
}
|
|
431
|
+
case TEPTRIS_ARRAY:
|
|
432
|
+
return put_node_array(b, key, n);
|
|
433
|
+
default:
|
|
434
|
+
return 1;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
static int asm_table_rows(teptris_builder *b, const teptris_plan *p,
|
|
439
|
+
const teptris_plan_result *res, uint32_t plan_idx);
|
|
440
|
+
|
|
441
|
+
static int asm_table_rows(teptris_builder *b, const teptris_plan *p,
|
|
442
|
+
const teptris_plan_result *res, uint32_t plan_idx) {
|
|
443
|
+
uint32_t n = teptris_plan_row_count(p, plan_idx);
|
|
444
|
+
for (uint32_t i = 0; i < n; i++) {
|
|
445
|
+
uint8_t kind = teptris_plan_result_kind_at(res, i);
|
|
446
|
+
if (kind == 0 /* MISSING */) {
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
const char *key = teptris_plan_row_name_at(p, plan_idx, i);
|
|
450
|
+
switch (kind) {
|
|
451
|
+
case 1 /* SCALAR */:
|
|
452
|
+
if (put_scalar_result(b, key, res, i) != 0) {
|
|
453
|
+
return 1;
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
case 2 /* ARRAY */: {
|
|
457
|
+
uint32_t n2 = teptris_plan_result_array_len_at(res, i);
|
|
458
|
+
uint32_t sub = teptris_plan_row_sub_at(p, plan_idx, i);
|
|
459
|
+
if (teptris_builder_open_array(b, key, strlen(key)) != TEPTRIS_OK) {
|
|
460
|
+
return 1;
|
|
461
|
+
}
|
|
462
|
+
for (uint32_t j = 0; j < n2; j++) {
|
|
463
|
+
if (teptris_plan_result_array_kind_at(res, i, j) == 3 /* TABLE */) {
|
|
464
|
+
teptris_plan_result *entry =
|
|
465
|
+
teptris_plan_result_array_entry_at(res, i, j);
|
|
466
|
+
if (entry == NULL) {
|
|
467
|
+
return 1;
|
|
468
|
+
}
|
|
469
|
+
int rc = asm_table_rows(b, p, entry, sub);
|
|
470
|
+
teptris_plan_result_view_free(entry);
|
|
471
|
+
if (rc != 0) {
|
|
472
|
+
return 1;
|
|
473
|
+
}
|
|
474
|
+
} else if (put_array_scalar_result(b, res, i, j) != 0) {
|
|
475
|
+
return 1;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (teptris_builder_close(b) != TEPTRIS_OK) {
|
|
479
|
+
return 1;
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
case 3 /* TABLE */: {
|
|
484
|
+
teptris_plan_result *sub = teptris_plan_result_row_view(res, i);
|
|
485
|
+
if (sub == NULL) {
|
|
486
|
+
return 1;
|
|
487
|
+
}
|
|
488
|
+
uint32_t sub_idx = teptris_plan_row_sub_at(p, plan_idx, i);
|
|
489
|
+
if (teptris_builder_open_table(b, key, strlen(key))
|
|
490
|
+
!= TEPTRIS_OK) {
|
|
491
|
+
return 1;
|
|
492
|
+
}
|
|
493
|
+
int rc = asm_table_rows(b, p, sub, sub_idx);
|
|
494
|
+
teptris_plan_result_view_free(sub);
|
|
495
|
+
if (rc != 0 || teptris_builder_close(b) != TEPTRIS_OK) {
|
|
496
|
+
return 1;
|
|
497
|
+
}
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
case 4 /* RAW */: {
|
|
501
|
+
const teptris_node *raw = teptris_plan_result_raw_at(res, i);
|
|
502
|
+
if (raw == NULL) {
|
|
503
|
+
snprintf(last_error, sizeof last_error,
|
|
504
|
+
"plan asm: raw row %u has no node", (unsigned)i);
|
|
505
|
+
return 1;
|
|
506
|
+
}
|
|
507
|
+
/* put_node sets its own specific message */
|
|
508
|
+
if (put_node(b, key, strlen(key), raw) != 0) {
|
|
509
|
+
return 1;
|
|
510
|
+
}
|
|
511
|
+
break;
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
default:
|
|
515
|
+
snprintf(last_error, sizeof last_error,
|
|
516
|
+
"plan asm: row %u unexpected kind %d", (unsigned)i,
|
|
517
|
+
(int)kind);
|
|
518
|
+
return 1;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return 0;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
EMSCRIPTEN_KEEPALIVE
|
|
525
|
+
int teptris_wasm_plan_walk(void *plan, const char *data, size_t len) {
|
|
526
|
+
teptris_document *doc = NULL;
|
|
527
|
+
teptris_status st = teptris_parse(data, len, NULL, &doc);
|
|
528
|
+
if (st != TEPTRIS_OK || doc == NULL) {
|
|
529
|
+
if (doc != NULL) {
|
|
530
|
+
const teptris_error *e = teptris_document_error(doc);
|
|
531
|
+
snprintf(last_error, sizeof last_error, "%s", e->message);
|
|
532
|
+
last_error_line = (int)e->line;
|
|
533
|
+
last_error_column = (int)e->column;
|
|
534
|
+
teptris_document_free(doc);
|
|
535
|
+
} else {
|
|
536
|
+
snprintf(last_error, sizeof last_error, "parse failed");
|
|
537
|
+
}
|
|
538
|
+
return (int)st;
|
|
539
|
+
}
|
|
540
|
+
teptris_status wst;
|
|
541
|
+
teptris_plan_result *res = teptris_plan_walk(
|
|
542
|
+
(const teptris_plan *)plan, teptris_document_root(doc), &wst);
|
|
543
|
+
if (wst != TEPTRIS_OK || res == NULL) {
|
|
544
|
+
snprintf(last_error, sizeof last_error, "plan walk failed (%s)",
|
|
545
|
+
teptris_status_string(wst));
|
|
546
|
+
teptris_document_free(doc);
|
|
547
|
+
return (int)wst;
|
|
548
|
+
}
|
|
549
|
+
teptris_builder *b = teptris_builder_new();
|
|
550
|
+
int rc = 0;
|
|
551
|
+
if (b == NULL) {
|
|
552
|
+
snprintf(last_error, sizeof last_error,
|
|
553
|
+
"plan materialize: out of memory");
|
|
554
|
+
rc = TEPTRIS_ERR_STATE;
|
|
555
|
+
} else if (asm_table_rows(b, (const teptris_plan *)plan, res, 0) != 0) {
|
|
556
|
+
/* asm_table_rows set last_error with the failing row */
|
|
557
|
+
rc = TEPTRIS_ERR_STATE;
|
|
558
|
+
}
|
|
559
|
+
if (rc == 0) {
|
|
560
|
+
teptris_document *out = NULL;
|
|
561
|
+
st = teptris_builder_finish(b, &out);
|
|
562
|
+
teptris_builder_free(b);
|
|
563
|
+
if (st != TEPTRIS_OK) {
|
|
564
|
+
teptris_document_free(out);
|
|
565
|
+
teptris_document_free(doc);
|
|
566
|
+
teptris_plan_result_free(res);
|
|
567
|
+
return (int)st;
|
|
568
|
+
}
|
|
569
|
+
char *buf = NULL;
|
|
570
|
+
size_t blen = 0;
|
|
571
|
+
st = teptris_document_emit_json_natural(out, &buf, &blen);
|
|
572
|
+
teptris_document_free(out);
|
|
573
|
+
if (st != TEPTRIS_OK) {
|
|
574
|
+
teptris_document_free(doc);
|
|
575
|
+
teptris_plan_result_free(res);
|
|
576
|
+
return (int)st;
|
|
577
|
+
}
|
|
578
|
+
g_json = buf;
|
|
579
|
+
g_json_len = blen;
|
|
580
|
+
} else {
|
|
581
|
+
teptris_builder_free(b);
|
|
582
|
+
}
|
|
583
|
+
teptris_plan_result_free(res);
|
|
584
|
+
teptris_document_free(doc);
|
|
585
|
+
return rc;
|
|
586
|
+
}
|