embedded-react 0.2.3 → 0.4.0

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/qjsc-wasm.mjs ADDED
@@ -0,0 +1,83 @@
1
+ /*
2
+ * Copyright 2026 Cory Lamming
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // qjsc-wasm.mjs — compile a JS bundle to QuickJS bytecode using the prebuilt simulator `.wasm` (the SAME
18
+ // QuickJS that runs the app in the browser sim), so `embedded-react build` produces a device-ready
19
+ // bytecode container with NO native toolchain. The module is built with `-sENVIRONMENT=web,node`, so the
20
+ // same artifact that powers `dev` loads under Node here.
21
+
22
+ import {createRequire} from 'node:module';
23
+ import {dirname, resolve} from 'node:path';
24
+ import {fileURLToPath} from 'node:url';
25
+ import {existsSync} from 'node:fs';
26
+
27
+ const HERE = dirname(fileURLToPath(import.meta.url));
28
+
29
+ /**
30
+ * Compile JS source to a QuickJS bytecode blob via the prebuilt sim module.
31
+ *
32
+ * @param {string} jsSource The bundled app (esbuild IIFE output).
33
+ * @param {string} [simDir] Dir holding embedded-react.{js,wasm} (defaults to the package's sim/).
34
+ * @returns {Promise<Buffer>} The bytecode bytes.
35
+ */
36
+ export async function compileToBytecode(
37
+ jsSource,
38
+ simDir = resolve(HERE, 'sim'),
39
+ ) {
40
+ // The .cjs (not .js): this package is "type": "module", so Node would load the emscripten .js as ESM and
41
+ // its CommonJS factory export would never run. The .cjs is the same module forced to CommonJS for Node.
42
+ const loader = resolve(simDir, 'embedded-react.cjs');
43
+ if (!existsSync(loader)) {
44
+ throw new Error(
45
+ `prebuilt simulator module not found at ${loader} (a published package ships it; from source run tools/web-sim/build.mjs)`,
46
+ );
47
+ }
48
+ const require = createRequire(import.meta.url);
49
+ const factory = require(loader); // forced CommonJS → MODULARIZE factory
50
+ const Module = await factory();
51
+
52
+ const bytes = new TextEncoder().encode(jsSource);
53
+ // QuickJS's JS_Eval requires the source buffer to be NUL-terminated (buf[len] === 0). Allocate one
54
+ // extra byte and zero it: without the terminator the lexer reads an uninitialized sentinel and can
55
+ // stop early ("unexpected token ''") — a heap-state-dependent failure that only bites on larger inputs.
56
+ const srcPtr = Module._malloc(bytes.length + 1);
57
+ Module.HEAPU8.set(bytes, srcPtr);
58
+ Module.HEAPU8[srcPtr + bytes.length] = 0;
59
+ const outLenPtr = Module._malloc(4);
60
+
61
+ const compile = Module.cwrap('er_web_compile_bytecode', 'number', [
62
+ 'number',
63
+ 'number',
64
+ 'number',
65
+ ]);
66
+ const bcPtr = compile(srcPtr, bytes.length, outLenPtr);
67
+
68
+ // ALLOW_MEMORY_GROWTH=1 can detach views across the malloc/compile calls — read through a FRESH buffer.
69
+ const heap = () => new Uint8Array(Module.HEAPU8.buffer);
70
+ const bcLen = new DataView(heap().buffer).getUint32(outLenPtr, true);
71
+
72
+ Module._free(srcPtr);
73
+ Module._free(outLenPtr);
74
+ if (!bcPtr || !bcLen) {
75
+ if (bcPtr) Module._free(bcPtr);
76
+ throw new Error(
77
+ 'bytecode compile failed — check the bundle for a syntax error (see stderr above)',
78
+ );
79
+ }
80
+ const out = Buffer.from(heap().subarray(bcPtr, bcPtr + bcLen)); // copy out before freeing
81
+ Module._free(bcPtr);
82
+ return out;
83
+ }
@@ -0,0 +1,2 @@
1
+ var createEmbeddedReact=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else{}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");scriptDirectory=__dirname+"/";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,"/")}arguments_=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://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["k"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}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 wasmBinaryFile;function findWasmBinary(){return locateFile("embedded-react.wasm")}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&&!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(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["j"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,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 callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>num<INT53_MIN||num>INT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}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 __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset<winterOffset){stringToUTF8(winterName,std_name,17);stringToUTF8(summerName,dst_name,17)}else{stringToUTF8(winterName,dst_name,17);stringToUTF8(summerName,std_name,17)}};var _emscripten_get_now=()=>performance.now();var _emscripten_date_now=()=>Date.now();var nowIsMonotonic=1;var checkWasiClock=clock_id=>clock_id>=0&&clock_id<=3;function _clock_time_get(clk_id,ignored_precision,ptime){ignored_precision=bigintToI53Checked(ignored_precision);if(!checkWasiClock(clk_id)){return 28}var now;if(clk_id===0){now=_emscripten_date_now()}else if(nowIsMonotonic){now=_emscripten_get_now()}else{return 52}var nsec=Math.round(now*1e3*1e3);HEAP64[ptime>>3]=BigInt(nsec);return 0}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 _fd_close=fd=>52;function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);return 70}var printCharBuffers=[null,[],[]];var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;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 printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer));buffer.length=0}else{buffer.push(curr)}};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";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 getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};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 stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _malloc,_free,_er_web_init,_er_web_load_source,_er_web_compile_bytecode,_er_web_load_pack,_er_web_demo_scene,_er_web_resize,_er_web_pump,_er_web_touch,_er_web_reset,_er_web_framebuffer,_er_web_fb_width,_er_web_fb_height,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module["_malloc"]=_malloc=wasmExports["l"];Module["_free"]=_free=wasmExports["m"];Module["_er_web_init"]=_er_web_init=wasmExports["n"];Module["_er_web_load_source"]=_er_web_load_source=wasmExports["o"];Module["_er_web_compile_bytecode"]=_er_web_compile_bytecode=wasmExports["p"];Module["_er_web_load_pack"]=_er_web_load_pack=wasmExports["q"];Module["_er_web_demo_scene"]=_er_web_demo_scene=wasmExports["r"];Module["_er_web_resize"]=_er_web_resize=wasmExports["s"];Module["_er_web_pump"]=_er_web_pump=wasmExports["t"];Module["_er_web_touch"]=_er_web_touch=wasmExports["u"];Module["_er_web_reset"]=_er_web_reset=wasmExports["v"];Module["_er_web_framebuffer"]=_er_web_framebuffer=wasmExports["w"];Module["_er_web_fb_width"]=_er_web_fb_width=wasmExports["x"];Module["_er_web_fb_height"]=_er_web_fb_height=wasmExports["y"];__emscripten_stack_restore=wasmExports["z"];__emscripten_stack_alloc=wasmExports["A"];_emscripten_stack_get_current=wasmExports["B"]}var wasmImports={i:__abort_js,e:__localtime_js,f:__tzset_js,h:_clock_time_get,g:_emscripten_date_now,b:_emscripten_resize_heap,d:_fd_close,c:_fd_seek,a:_fd_write};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){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()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
2
+ ;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createEmbeddedReact;module.exports.default=createEmbeddedReact}else if(typeof define==="function"&&define["amd"])define([],()=>createEmbeddedReact);
@@ -1,2 +1,2 @@
1
- var createEmbeddedReact=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var arguments_=[];var thisProgram="./this.program";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;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 readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["k"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}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 wasmBinaryFile;function findWasmBinary(){return locateFile("embedded-react.wasm")}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){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["j"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,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 callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>num<INT53_MIN||num>INT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}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 __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset<winterOffset){stringToUTF8(winterName,std_name,17);stringToUTF8(summerName,dst_name,17)}else{stringToUTF8(winterName,dst_name,17);stringToUTF8(summerName,std_name,17)}};var _emscripten_get_now=()=>performance.now();var _emscripten_date_now=()=>Date.now();var nowIsMonotonic=1;var checkWasiClock=clock_id=>clock_id>=0&&clock_id<=3;function _clock_time_get(clk_id,ignored_precision,ptime){ignored_precision=bigintToI53Checked(ignored_precision);if(!checkWasiClock(clk_id)){return 28}var now;if(clk_id===0){now=_emscripten_date_now()}else if(nowIsMonotonic){now=_emscripten_get_now()}else{return 52}var nsec=Math.round(now*1e3*1e3);HEAP64[ptime>>3]=BigInt(nsec);return 0}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 _fd_close=fd=>52;function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);return 70}var printCharBuffers=[null,[],[]];var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;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 printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer));buffer.length=0}else{buffer.push(curr)}};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";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 getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};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 stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _malloc,_free,_er_web_init,_er_web_load_source,_er_web_load_pack,_er_web_demo_scene,_er_web_resize,_er_web_pump,_er_web_touch,_er_web_reset,_er_web_framebuffer,_er_web_fb_width,_er_web_fb_height,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module["_malloc"]=_malloc=wasmExports["l"];Module["_free"]=_free=wasmExports["m"];Module["_er_web_init"]=_er_web_init=wasmExports["n"];Module["_er_web_load_source"]=_er_web_load_source=wasmExports["o"];Module["_er_web_load_pack"]=_er_web_load_pack=wasmExports["p"];Module["_er_web_demo_scene"]=_er_web_demo_scene=wasmExports["q"];Module["_er_web_resize"]=_er_web_resize=wasmExports["r"];Module["_er_web_pump"]=_er_web_pump=wasmExports["s"];Module["_er_web_touch"]=_er_web_touch=wasmExports["t"];Module["_er_web_reset"]=_er_web_reset=wasmExports["u"];Module["_er_web_framebuffer"]=_er_web_framebuffer=wasmExports["v"];Module["_er_web_fb_width"]=_er_web_fb_width=wasmExports["w"];Module["_er_web_fb_height"]=_er_web_fb_height=wasmExports["x"];__emscripten_stack_restore=wasmExports["y"];__emscripten_stack_alloc=wasmExports["z"];_emscripten_stack_get_current=wasmExports["A"]}var wasmImports={i:__abort_js,e:__localtime_js,f:__tzset_js,h:_clock_time_get,g:_emscripten_date_now,b:_emscripten_resize_heap,d:_fd_close,c:_fd_seek,a:_fd_write};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){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()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
1
+ var createEmbeddedReact=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else{}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");scriptDirectory=__dirname+"/";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,"/")}arguments_=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://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["k"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}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 wasmBinaryFile;function findWasmBinary(){return locateFile("embedded-react.wasm")}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&&!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(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["j"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,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 callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>abort("");var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var MONTH_DAYS_LEAP_CUMULATIVE=[0,31,60,91,121,152,182,213,244,274,305,335];var MONTH_DAYS_REGULAR_CUMULATIVE=[0,31,59,90,120,151,181,212,243,273,304,334];var ydayFromDate=date=>{var leap=isLeapYear(date.getFullYear());var monthDaysCumulative=leap?MONTH_DAYS_LEAP_CUMULATIVE:MONTH_DAYS_REGULAR_CUMULATIVE;var yday=monthDaysCumulative[date.getMonth()]+date.getDate()-1;return yday};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>num<INT53_MIN||num>INT53_MAX?NaN:Number(num);function __localtime_js(time,tmPtr){time=bigintToI53Checked(time);var date=new Date(time*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var yday=ydayFromDate(date)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}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 __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset<winterOffset){stringToUTF8(winterName,std_name,17);stringToUTF8(summerName,dst_name,17)}else{stringToUTF8(winterName,dst_name,17);stringToUTF8(summerName,std_name,17)}};var _emscripten_get_now=()=>performance.now();var _emscripten_date_now=()=>Date.now();var nowIsMonotonic=1;var checkWasiClock=clock_id=>clock_id>=0&&clock_id<=3;function _clock_time_get(clk_id,ignored_precision,ptime){ignored_precision=bigintToI53Checked(ignored_precision);if(!checkWasiClock(clk_id)){return 28}var now;if(clk_id===0){now=_emscripten_date_now()}else if(nowIsMonotonic){now=_emscripten_get_now()}else{return 52}var nsec=Math.round(now*1e3*1e3);HEAP64[ptime>>3]=BigInt(nsec);return 0}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 _fd_close=fd=>52;function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(offset);return 70}var printCharBuffers=[null,[],[]];var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;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 printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer));buffer.length=0}else{buffer.push(curr)}};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";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 getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};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 stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}Module["ccall"]=ccall;Module["cwrap"]=cwrap;var _malloc,_free,_er_web_init,_er_web_load_source,_er_web_compile_bytecode,_er_web_load_pack,_er_web_demo_scene,_er_web_resize,_er_web_pump,_er_web_touch,_er_web_reset,_er_web_framebuffer,_er_web_fb_width,_er_web_fb_height,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current;function assignWasmExports(wasmExports){Module["_malloc"]=_malloc=wasmExports["l"];Module["_free"]=_free=wasmExports["m"];Module["_er_web_init"]=_er_web_init=wasmExports["n"];Module["_er_web_load_source"]=_er_web_load_source=wasmExports["o"];Module["_er_web_compile_bytecode"]=_er_web_compile_bytecode=wasmExports["p"];Module["_er_web_load_pack"]=_er_web_load_pack=wasmExports["q"];Module["_er_web_demo_scene"]=_er_web_demo_scene=wasmExports["r"];Module["_er_web_resize"]=_er_web_resize=wasmExports["s"];Module["_er_web_pump"]=_er_web_pump=wasmExports["t"];Module["_er_web_touch"]=_er_web_touch=wasmExports["u"];Module["_er_web_reset"]=_er_web_reset=wasmExports["v"];Module["_er_web_framebuffer"]=_er_web_framebuffer=wasmExports["w"];Module["_er_web_fb_width"]=_er_web_fb_width=wasmExports["x"];Module["_er_web_fb_height"]=_er_web_fb_height=wasmExports["y"];__emscripten_stack_restore=wasmExports["z"];__emscripten_stack_alloc=wasmExports["A"];_emscripten_stack_get_current=wasmExports["B"]}var wasmImports={i:__abort_js,e:__localtime_js,f:__tzset_js,h:_clock_time_get,g:_emscripten_date_now,b:_emscripten_resize_heap,d:_fd_close,c:_fd_seek,a:_fd_write};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){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()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})}
2
2
  ;return moduleRtn}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createEmbeddedReact;module.exports.default=createEmbeddedReact}else if(typeof define==="function"&&define["amd"])define([],()=>createEmbeddedReact);
Binary file
package/sim-server.mjs CHANGED
@@ -23,18 +23,27 @@
23
23
  // Used by the consumer CLI (cli.mjs → `npx embedded-react dev` / `export`) and the repo dev loop
24
24
  // (tools/web-sim/dev.mjs). The only differences are paths, passed in here.
25
25
 
26
- import { createServer } from 'node:http';
27
- import { readFile } from 'node:fs/promises';
28
- import { existsSync, readFileSync, statSync } from 'node:fs';
29
- import { createRequire } from 'node:module';
30
- import { pathToFileURL } from 'node:url';
31
- import { basename, dirname, extname, relative, resolve } from 'node:path';
32
-
33
- const HERE = dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1'));
26
+ import {createServer} from 'node:http';
27
+ import {readFile} from 'node:fs/promises';
28
+ import {existsSync, readFileSync, statSync} from 'node:fs';
29
+ import {createRequire} from 'node:module';
30
+ import {pathToFileURL} from 'node:url';
31
+ import {basename, dirname, extname, relative, resolve} from 'node:path';
32
+
33
+ const HERE = dirname(
34
+ new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1'),
35
+ );
34
36
  const require = createRequire(import.meta.url);
35
37
  const esbuild = require('esbuild');
36
- const { bakeAssetPack } = await import(pathToFileURL(resolve(HERE, 'assets/index.mjs')).href);
37
- const { transformPersist, shouldPersist } = await import(pathToFileURL(resolve(HERE, 'persist-transform.mjs')).href);
38
+ const {bakeAssetPack} = await import(
39
+ pathToFileURL(resolve(HERE, 'assets/index.mjs')).href
40
+ );
41
+ const {registerSvgVectorLoader} = await import(
42
+ pathToFileURL(resolve(HERE, 'assets/svg-loader.mjs')).href
43
+ );
44
+ const {transformPersist, shouldPersist} = await import(
45
+ pathToFileURL(resolve(HERE, 'persist-transform.mjs')).href
46
+ );
38
47
 
39
48
  const MIME = {
40
49
  '.html': 'text/html; charset=utf-8',
@@ -42,8 +51,8 @@ const MIME = {
42
51
  '.wasm': 'application/wasm',
43
52
  '.pack': 'application/octet-stream',
44
53
  };
45
- const assetName = (p) => basename(p).replace(/\.[^.]+$/, '');
46
- const mtime = (p) => {
54
+ const assetName = p => basename(p).replace(/\.[^.]+$/, '');
55
+ const mtime = p => {
47
56
  try {
48
57
  return statSync(p).mtimeMs;
49
58
  } catch {
@@ -62,7 +71,15 @@ const mtime = (p) => {
62
71
  * @param {() => void} [o.onRebuilt] Called after each successful build + asset bake (e.g. broadcast reload).
63
72
  * @returns {{ options: object, bundlePath: string, packPath: string }}
64
73
  */
65
- function createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist = true, onRebuilt }) {
74
+ function createBundle({
75
+ entry,
76
+ projectRoot,
77
+ libSrc,
78
+ nodePaths,
79
+ outDir,
80
+ persist = true,
81
+ onRebuilt,
82
+ }) {
66
83
  const bundlePath = resolve(outDir, 'app.js');
67
84
  const packPath = resolve(outDir, 'assets.pack');
68
85
  const projNorm = projectRoot.replace(/\\/g, '/');
@@ -73,33 +90,62 @@ function createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist =
73
90
  async function bakePack() {
74
91
  const discoveredSizes = [
75
92
  ...new Set(
76
- [...readFileSync(bundlePath, 'utf8').matchAll(/\bfontSize\s*:\s*(\d+(?:\.\d+)?)/g)].map((m) => Math.round(Number(m[1]))),
93
+ [
94
+ ...readFileSync(bundlePath, 'utf8').matchAll(
95
+ /\bfontSize\s*:\s*(\d+(?:\.\d+)?)/g,
96
+ ),
97
+ ].map(m => Math.round(Number(m[1]))),
77
98
  ),
78
99
  ].sort((a, b) => a - b);
79
100
 
80
101
  let cfg = {};
81
102
  const cp = resolve(projectRoot, 'assets.config.js');
82
- if (existsSync(cp)) cfg = (await import(`${pathToFileURL(cp).href}?t=${mtime(cp)}`)).default || {};
103
+ if (existsSync(cp))
104
+ cfg =
105
+ (await import(`${pathToFileURL(cp).href}?t=${mtime(cp)}`)).default ||
106
+ {};
83
107
  const fontConfig = cfg.fonts || {};
84
108
 
85
109
  const fontJobs = [...fonts.entries()].map(([family, path]) => {
86
110
  const fc = fontConfig[family] || {};
87
- const sizes = fc.sizes && fc.sizes.length ? fc.sizes : discoveredSizes.length ? discoveredSizes : [16];
88
- return { path, family, sizes, bpp: fc.bpp ?? 4, glyphs: fc.glyphs ?? 'ascii' };
111
+ const sizes =
112
+ fc.sizes && fc.sizes.length
113
+ ? fc.sizes
114
+ : discoveredSizes.length
115
+ ? discoveredSizes
116
+ : [16];
117
+ return {
118
+ path,
119
+ family,
120
+ sizes,
121
+ bpp: fc.bpp ?? 4,
122
+ glyphs: fc.glyphs ?? 'ascii',
123
+ };
89
124
  });
90
- const imageJobs = [...images.entries()].map(([name, path]) => ({ path, name }));
125
+ const imageJobs = [...images.entries()].map(([name, path]) => ({
126
+ path,
127
+ name,
128
+ }));
91
129
 
92
130
  const sig = JSON.stringify({
93
- i: imageJobs.map((j) => [j.name, j.path, mtime(j.path)]).sort(),
94
- f: fontJobs.map((j) => [j.family, j.path, mtime(j.path), j.sizes, j.bpp, j.glyphs]).sort(),
131
+ i: imageJobs.map(j => [j.name, j.path, mtime(j.path)]).sort(),
132
+ f: fontJobs
133
+ .map(j => [j.family, j.path, mtime(j.path), j.sizes, j.bpp, j.glyphs])
134
+ .sort(),
95
135
  });
96
136
  if (sig === lastAssetSig) return;
97
137
  lastAssetSig = sig;
98
138
  if (!imageJobs.length && !fontJobs.length) return; // built-in font only → no pack
99
139
 
100
140
  try {
101
- const s = bakeAssetPack({ images: imageJobs, fonts: fontJobs, outPath: packPath });
102
- console.log(` assets → ${s.images} image(s), ${s.fonts} font size(s), ${s.bytes} B`);
141
+ const s = bakeAssetPack({
142
+ images: imageJobs,
143
+ fonts: fontJobs,
144
+ outPath: packPath,
145
+ });
146
+ console.log(
147
+ ` assets → ${s.images} image(s), ${s.fonts} font size(s), ${s.bytes} B`,
148
+ );
103
149
  } catch (e) {
104
150
  console.error(` asset bake failed: ${e.message}`);
105
151
  }
@@ -113,9 +159,9 @@ function createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist =
113
159
  platform: 'neutral',
114
160
  target: 'es2020',
115
161
  jsx: 'automatic',
116
- alias: { 'embedded-react': libSrc },
162
+ alias: {'embedded-react': libSrc},
117
163
  nodePaths,
118
- define: { 'process.env.NODE_ENV': '"production"' },
164
+ define: {'process.env.NODE_ENV': '"production"'},
119
165
  legalComments: 'none',
120
166
  logLevel: 'silent',
121
167
  plugins: [
@@ -126,25 +172,38 @@ function createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist =
126
172
  images.clear();
127
173
  fonts.clear();
128
174
  });
129
- b.onLoad({ filter: /\.(jsx?|tsx?)$/ }, (a) => {
175
+ b.onLoad({filter: /\.(jsx?|tsx?)$/}, a => {
130
176
  // Transform ONLY the app's own source — never dependencies (see shouldPersist: excluding
131
177
  // node_modules is what stops the library's usePersistentState being rewritten to call itself).
132
178
  if (!persist || !shouldPersist(a.path, projNorm)) return undefined;
133
179
  try {
134
- return { contents: transformPersist(readFileSync(a.path, 'utf8'), relative(projectRoot, a.path).replace(/\\/g, '/')), loader: 'jsx' };
180
+ return {
181
+ contents: transformPersist(
182
+ readFileSync(a.path, 'utf8'),
183
+ relative(projectRoot, a.path).replace(/\\/g, '/'),
184
+ ),
185
+ loader: 'jsx',
186
+ };
135
187
  } catch (e) {
136
- return { errors: [{ text: `persist transform: ${e.message}` }] };
188
+ return {errors: [{text: `persist transform: ${e.message}`}]};
137
189
  }
138
190
  });
139
- b.onLoad({ filter: /\.(png|jpe?g|webp|gif|bmp)$/i }, (a) => {
191
+ b.onLoad({filter: /\.(png|jpe?g|webp|gif|bmp)$/i}, a => {
140
192
  images.set(assetName(a.path), a.path);
141
- return { contents: `module.exports = ${JSON.stringify(assetName(a.path))};`, loader: 'js' };
193
+ return {
194
+ contents: `module.exports = ${JSON.stringify(assetName(a.path))};`,
195
+ loader: 'js',
196
+ };
142
197
  });
143
- b.onLoad({ filter: /\.(ttf|otf)$/i }, (a) => {
198
+ b.onLoad({filter: /\.(ttf|otf)$/i}, a => {
144
199
  fonts.set(assetName(a.path), a.path);
145
- return { contents: `module.exports = ${JSON.stringify(assetName(a.path))};`, loader: 'js' };
200
+ return {
201
+ contents: `module.exports = ${JSON.stringify(assetName(a.path))};`,
202
+ loader: 'js',
203
+ };
146
204
  });
147
- b.onEnd(async (r) => {
205
+ registerSvgVectorLoader(b, (name, p) => images.set(name, p)); // raster-fallback SVGs join the image pack
206
+ b.onEnd(async r => {
148
207
  if (r.errors.length) {
149
208
  console.error(`✗ build failed (${r.errors.length} error(s))`);
150
209
  return;
@@ -157,15 +216,28 @@ function createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist =
157
216
  ],
158
217
  };
159
218
 
160
- return { options, bundlePath, packPath };
219
+ return {options, bundlePath, packPath};
161
220
  }
162
221
 
163
222
  /**
164
223
  * One-shot bundle + asset bake into outDir (app.js [+ assets.pack]). For the static export.
165
224
  * Persist transform is off (a static page has no hot reload to preserve state across).
166
225
  */
167
- export async function buildApp({ entry, projectRoot, libSrc, nodePaths, outDir }) {
168
- const { options } = createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist: false });
226
+ export async function buildApp({
227
+ entry,
228
+ projectRoot,
229
+ libSrc,
230
+ nodePaths,
231
+ outDir,
232
+ }) {
233
+ const {options} = createBundle({
234
+ entry,
235
+ projectRoot,
236
+ libSrc,
237
+ nodePaths,
238
+ outDir,
239
+ persist: false,
240
+ });
169
241
  await esbuild.build(options);
170
242
  }
171
243
 
@@ -177,16 +249,34 @@ export async function buildApp({ entry, projectRoot, libSrc, nodePaths, outDir }
177
249
  * @param {string[]} o.nodePaths
178
250
  * @param {number} o.port
179
251
  */
180
- export async function runDevServer({ entry, projectRoot, libSrc, nodePaths, indexHtml, simDir, outDir, port, label }) {
252
+ export async function runDevServer({
253
+ entry,
254
+ projectRoot,
255
+ libSrc,
256
+ nodePaths,
257
+ indexHtml,
258
+ simDir,
259
+ outDir,
260
+ port,
261
+ label,
262
+ }) {
181
263
  const clients = new Set();
182
264
  const broadcastReload = () => {
183
265
  for (const res of clients) res.write('data: reload\n\n');
184
266
  };
185
267
 
186
- const { options } = createBundle({ entry, projectRoot, libSrc, nodePaths, outDir, persist: true, onRebuilt: () => {
187
- console.log('↻ rebuilt → reloading');
188
- broadcastReload();
189
- } });
268
+ const {options} = createBundle({
269
+ entry,
270
+ projectRoot,
271
+ libSrc,
272
+ nodePaths,
273
+ outDir,
274
+ persist: true,
275
+ onRebuilt: () => {
276
+ console.log('↻ rebuilt → reloading');
277
+ broadcastReload();
278
+ },
279
+ });
190
280
 
191
281
  const ctx = await esbuild.context(options);
192
282
  await ctx.rebuild();
@@ -196,15 +286,26 @@ export async function runDevServer({ entry, projectRoot, libSrc, nodePaths, inde
196
286
  // outDir. The page references ./public/<name>. window.__erHot is injected so the page connects to /reload.
197
287
  const send = async (res, file) => {
198
288
  try {
199
- res.writeHead(200, { 'content-type': MIME[extname(file)] || 'application/octet-stream', 'cache-control': 'no-store' }).end(await readFile(file));
289
+ res
290
+ .writeHead(200, {
291
+ 'content-type': MIME[extname(file)] || 'application/octet-stream',
292
+ 'cache-control': 'no-store',
293
+ })
294
+ .end(await readFile(file));
200
295
  } catch {
201
296
  res.writeHead(404).end('not found');
202
297
  }
203
298
  };
204
299
  const server = createServer(async (req, res) => {
205
- const path = decodeURIComponent(new URL(req.url, 'http://localhost').pathname);
300
+ const path = decodeURIComponent(
301
+ new URL(req.url, 'http://localhost').pathname,
302
+ );
206
303
  if (path === '/reload') {
207
- res.writeHead(200, { 'content-type': 'text/event-stream', 'cache-control': 'no-cache', connection: 'keep-alive' });
304
+ res.writeHead(200, {
305
+ 'content-type': 'text/event-stream',
306
+ 'cache-control': 'no-cache',
307
+ connection: 'keep-alive',
308
+ });
208
309
  res.write('retry: 1000\n\n');
209
310
  clients.add(res);
210
311
  req.on('close', () => clients.delete(res));
@@ -212,8 +313,16 @@ export async function runDevServer({ entry, projectRoot, libSrc, nodePaths, inde
212
313
  }
213
314
  if (path === '/' || path === '/index.html') {
214
315
  try {
215
- const html = (await readFile(indexHtml, 'utf8')).replace('</head>', '<script>window.__erHot=true</script></head>');
216
- res.writeHead(200, { 'content-type': MIME['.html'], 'cache-control': 'no-store' }).end(html);
316
+ const html = (await readFile(indexHtml, 'utf8')).replace(
317
+ '</head>',
318
+ '<script>window.__erHot=true</script></head>',
319
+ );
320
+ res
321
+ .writeHead(200, {
322
+ 'content-type': MIME['.html'],
323
+ 'cache-control': 'no-store',
324
+ })
325
+ .end(html);
217
326
  } catch {
218
327
  res.writeHead(404).end('not found');
219
328
  }
@@ -221,13 +330,16 @@ export async function runDevServer({ entry, projectRoot, libSrc, nodePaths, inde
221
330
  }
222
331
  if (path.startsWith('/public/')) {
223
332
  const name = basename(path); // flat filename only
224
- const dir = name === 'embedded-react.js' || name === 'embedded-react.wasm' ? simDir : outDir;
333
+ const dir =
334
+ name === 'embedded-react.js' || name === 'embedded-react.wasm'
335
+ ? simDir
336
+ : outDir;
225
337
  return void send(res, resolve(dir, name));
226
338
  }
227
339
  res.writeHead(404).end('not found');
228
340
  });
229
341
 
230
- await new Promise((r) => server.listen(port, r));
342
+ await new Promise(r => server.listen(port, r));
231
343
  console.log(`embedded-react WASM sim → http://localhost:${port}/`);
232
344
  console.log(`watching ${label} — edit & save to hot-reload. Ctrl-C to quit.`);
233
345
 
@@ -240,5 +352,5 @@ export async function runDevServer({ entry, projectRoot, libSrc, nodePaths, inde
240
352
  };
241
353
  process.on('SIGINT', shutdown);
242
354
  process.on('SIGTERM', shutdown);
243
- return { ctx, server };
355
+ return {ctx, server};
244
356
  }