diff --git a/bun.lock b/bun.lock index ac452a2a0..501a92f2d 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 1, "workspaces": { "": { "name": "haskell-miso", @@ -9,7 +10,7 @@ "typescript": "^5.8.3", }, "devDependencies": { - "@happy-dom/global-registrator": "^17.5.6", + "@happy-dom/global-registrator": "latest", "@types/bun": "latest", "prettier": "3.5.3", }, @@ -19,21 +20,27 @@ }, }, "packages": { - "@happy-dom/global-registrator": ["@happy-dom/global-registrator@17.5.6", "", { "dependencies": { "happy-dom": "^17.5.6" } }, "sha512-nOUwjNp1GJUgAE8cVHIWgOgCUaxTCQBbVbbuapf2rEvXVh4aauyZ/mgiLbMXSI3Xz8HgGbETkxeJRFdKIoYCzA=="], + "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.6.0", "", { "dependencies": { "@types/node": ">=20.0.0", "happy-dom": "^20.6.0" } }, "sha512-Ulzos8Xbuo7FLXUsQGhHXgctABRG5YAxUzmJTX+kC4HzanmXiIlqItwmzPfLP4alEnPXUMA3UCJwOAsYDRpPfA=="], "@lcov-viewer/cli": ["@lcov-viewer/cli@1.3.0", "", { "dependencies": { "commander": "^9.3.0" }, "bin": { "lcov-viewer": "lib/index.js" } }, "sha512-A9altXh2ZyeuagYZsJqVja6WMlgGJGcV+SHOOgIZB+CA2bfk78vgOqrPJrWg+IflFpoEzo1QeqwH4WbKSM4d9A=="], - "@types/bun": ["@types/bun@1.2.14", "", { "dependencies": { "bun-types": "1.2.14" } }, "sha512-VsFZKs8oKHzI7zwvECiAJ5oSorWndIWEVhfbYqZd4HI/45kzW7PN2Rr5biAzvGvRuNmYLSANY+H59ubHq8xw7Q=="], + "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="], - "@types/node": ["@types/node@22.13.14", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w=="], + "@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="], - "bun-types": ["bun-types@1.2.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-Kuh4Ub28ucMRWeiUUWMHsT9Wcbr4H3kLIO72RZZElSDxSu7vpetRvxIUDUaW6QtaIeixIpm7OXtNnZPf82EzwA=="], + "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], + + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + + "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="], "commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + "fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "happy-dom": ["happy-dom@17.5.6", "", { "dependencies": { "webidl-conversions": "^7.0.0", "whatwg-mimetype": "^3.0.0" } }, "sha512-B4U6jKuiizwCJ2WP0YreQmRdeBrHKOXhpz7YUbbwdSAKfWEhdG4UfWZOZTZ5Oejs/9yJtk7xmbfp8YdVL9LVFA=="], + "happy-dom": ["happy-dom@20.6.0", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^6.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-a+Sz2bPai3rajDuE82Y4B0OxlXJ19ckUjyfWDmeCAs8ZbEbnqtwzV9d4CVhQjWIuOBTOw8rhlxNeaSCHeknXRQ=="], "playwright": ["playwright@1.53.2", "", { "dependencies": { "playwright-core": "1.53.2" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A=="], @@ -41,12 +48,12 @@ "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], - "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], + + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], } } diff --git a/js/miso.js b/js/miso.js index 29d076262..c107562ff 100644 --- a/js/miso.js +++ b/js/miso.js @@ -238,6 +238,9 @@ function drill(c) { return c.child.domRef; } } +function bts() { + return __BACKGROUND__; +} // ts/miso/dom.ts function diff(c, n, parent, context) { @@ -1108,6 +1111,7 @@ var drawingContext = { // ts/index.ts globalThis["miso"] = { + bts, hydrationContext, eventContext, drawingContext, diff --git a/js/miso.prod.js b/js/miso.prod.js index 2fc65a198..c5c311b00 100644 --- a/js/miso.prod.js +++ b/js/miso.prod.js @@ -1 +1 @@ -var F="1.9.0.0";function L(U,z){var G=function(){var K=document.getElementById(U);if(K&&K.focus)K.focus()};z>0?setTimeout(G,z):G()}function I(U,z){var G=function(){var K=document.getElementById(U);if(K&&K.blur)K.blur()};z>0?setTimeout(G,z):G()}function w(U,z){var G=function(){var K=document.getElementById(U);if(K&&typeof K.select==="function")K.select()};z>0?setTimeout(G,z):G()}function V(U,z,G,K){var H=function(){var X=document.getElementById(U);if(X&&typeof X.setSelectionRange==="function")X.setSelectionRange(z,G,"none")};K>0?setTimeout(H,K):H()}function O(U,z,G,K,H,X,Q){var Z={method:z,headers:K};if(G)Z.body=G;let _={},$=null;try{fetch(U,Z).then((Y)=>{$=Y.status;for(let[W,J]of Y.headers)_[W]=J;if(!Y.ok)throw new Error(Y.statusText);if(Q=="json")return Y.json();else if(Q=="text")return Y.text();else if(Q==="arrayBuffer")return Y.arrayBuffer();else if(Q==="blob")return Y.blob();else if(Q==="bytes")return Y.bytes();else if(Q==="formData")return Y.formData();else if(Q==="none")return H({error:null,body:null,headers:_,status:$})}).then((Y)=>H({error:null,body:Y,headers:_,status:$})).catch((Y)=>X({error:null,body:Y,headers:_,status:$}))}catch(Y){X({body:null,error:Y.message,headers:_,status:$})}}function P(U,z,G,K,H,X,Q,Z,_){try{let $=new WebSocket(U);return $.onopen=function(){z()},$.onclose=function(Y){G(Y)},$.onerror=function(Y){console.error(Y),Z("WebSocket error received")},$.onmessage=function(Y){if(typeof Y.data==="string")try{if(_){if(K)K(Y.data);return}let W=JSON.parse(Y.data);if(H)H(W)}catch(W){if(_&&K)K(Y.data);else Z(W.message)}else if(Y.data instanceof Blob){if(X)X(Y.data)}else if(Y.data instanceof ArrayBuffer){if(Q)Q(Y.data)}else console.error("Received unknown message type from WebSocket",Y),Z("Unknown message received from WebSocket")},$}catch($){Z($.message)}}function f(U){if(U)U.close(),U=null}function j(U,z){if(z&&U&&U.readyState===WebSocket.OPEN)U.send(z)}function b(U,z,G,K,H,X){try{let Q=new EventSource(U);return Q.onopen=function(){z()},Q.onerror=function(){H("EventSource error received")},Q.onmessage=function(Z){try{if(X){if(G)G(Z.data);return}let _=JSON.parse(Z.data);if(K)K(_)}catch(_){if(X&&G)G(Z.data);else H(_.message)}},Q}catch(Q){H(Q.message)}}function T(U){if(U)U.close(),U=null}function k(U,z){if(!U.classList)U.classList=new Set;for(let G of z)for(let K of G.trim().split(" "))if(K)U.classList.add(K)}function h(U,z){if(!U.parent)return;z.nextSibling=U.nextSibling?null:U.nextSibling,z.parent=U.parent,U.parent.child=z}function g(U,z={}){let G=Object.keys(z),K=Object.values(z);return new Function(...G,U)(...K)}function m(U){if(U===null||U===void 0)return 0;if(typeof U==="number")return 1;if(typeof U==="string")return 2;if(typeof U==="boolean")return 3;if(Array.isArray(U))return 4;return 5}function y(U){return function(){U|=0,U=U+2654435769|0;var z=U^U>>>15;return z=Math.imul(z,2246822507),z=z^z>>>13,z=Math.imul(z,3266489909),((z^z>>>16)>>>0)/4294967296}}function u(){let U=new Uint32Array(1);return crypto.getRandomValues(U)[0]}function v(){return Math.random()}function q(U){switch(U.type){case 0:return S(U);default:return U.domRef}}function S(U){if(!U.child)throw new Error("'drill' called on an unmounted Component. This should never happen, please make an issue.");switch(U.child.type){case 0:return S(U.child);default:return U.child.domRef}}function A(U,z,G,K){if(!U&&!z)return;else if(!U)BU(z,G,K);else if(!z)c(U,G,K);else if(U.type===2&&z.type===2)XU(U,z,K);else if(U.type===0&&z.type===0){if(z.key===U.key){if(z.child=U.child,z.componentId=U.componentId,U.child)U.child.parent=z;return}l(U,z,G,K)}else if(U.type===1&&z.type===1)if(z.tag===U.tag&&z.key===U.key)z.domRef=U.domRef,o(U,z,K);else l(U,z,G,K);else l(U,z,G,K)}function XU(U,z,G){if(U.text!==z.text)G.setTextContent(U.domRef,z.text);z.domRef=U.domRef;return}function l(U,z,G,K){switch(U.type){case 2:break;default:M(U);break}switch(i(G,1,q(U),z,K),U.type){case 2:break;default:R(U);break}}function c(U,z,G){switch(U.type){case 2:break;default:M(U);break}switch(G.removeChild(z,q(U)),U.type){case 2:break;default:R(U);break}}function R(U){switch(YU(U),U.type){case 1:for(let z of U.children)if(z.type===1||z.type===0)R(z);break;case 0:if(U.child){if(U.child.type===1||U.child.type===0)R(U.child)}break}}function YU(U){if(U.type===1&&U.onDestroyed)U.onDestroyed();if(U.type===0)DU(U)}function ZU(U){switch(U.type){case 0:break;case 1:if(U.onBeforeDestroyed)U.onBeforeDestroyed();break;default:break}}function M(U){switch(ZU(U),U.type){case 1:for(let z of U.children){if(z.type===2)continue;M(z)}break;case 0:if(U.child){if(U.child.type===1||U.child.type===0)M(U.child)}break}}function o(U,z,G){_U(U?U.props:{},z.props,z.domRef,z.ns==="svg",G),$U(U?U.classList:null,z.classList,z.domRef,G),WU(U?U.css:{},z.css,z.domRef,G),AU(U?U.children:[],z.children,z.domRef,G),EU(z)}function $U(U,z,G,K){if(!U&&!z)return;if(!U){for(let H of z)K.addClass(H,G);return}if(!z){for(let H of U)K.removeClass(H,G);return}for(let H of U)if(!z.has(H))K.removeClass(H,G);for(let H of z)if(!U.has(H))K.addClass(H,G);return}function _U(U,z,G,K,H){var X;for(let Q in U)if(X=z[Q],X===void 0)if(K||!(Q in G)||Q==="disabled")H.removeAttribute(G,Q);else H.setAttribute(G,Q,"");else{if(X===U[Q]&&Q!=="checked"&&Q!=="value")continue;if(K)if(Q==="href")H.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",X);else H.setAttribute(G,Q,X);else if(Q in G&&!(Q==="list"||Q==="form"))G[Q]=X;else H.setAttribute(G,Q,X)}for(let Q in z){if(U&&U[Q])continue;if(X=z[Q],K)if(Q==="href")H.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",X);else H.setAttribute(G,Q,X);else if(Q in G&&!(Q==="list"||Q==="form"))G[Q]=z[Q];else H.setAttribute(G,Q,X)}}function WU(U,z,G,K){K.setInlineStyle(U,z,G)}function qU(U,z){if(U.length===0||z.length===0)return!1;for(var G=0;GZ&&H>Q)break;if($=z[X],Y=z[Z],J=U[H],W=U[Q],H>Q)A(null,$,G,K),N(G,$,J,K),U.splice(X,0,$),X++;else if(X>Z){_=Q;while(Q>=H)c(U[Q--],G,K);U.splice(H,_-H+1);break}else if(J.key===$.key)A(U[H++],z[X++],G,K);else if(W.key===Y.key)A(U[Q--],z[Z--],G,K);else if(J.key===Y.key&&$.key===W.key)NU(W,J,G,K),MU(U,H,Q),A(U[H++],z[X++],G,K),A(U[Q--],z[Z--],G,K);else if(J.key===Y.key)N(G,J,W.nextSibling,K),U.splice(Q,0,U.splice(H,1)[0]),A(U[Q--],z[Z--],G,K);else if(W.key===$.key)N(G,W,J,K),U.splice(H,0,U.splice(Q,1)[0]),A(U[H++],$,G,K),X++;else{C=!1,_=H;while(_<=Q){if(U[_].key===$.key){C=!0,r=U[_];break}_++}if(C)U.splice(H,0,U.splice(_,1)[0]),A(U[H++],$,G,K),N(G,r,U[H],K),X++;else i(G,2,q(J),$,K),U.splice(H++,0,$),X++,Q++}}}function MU(U,z,G){let K=U[z];U[z]=U[G],U[G]=K}function UU(U,z,G,K,H){for(let X of z)H.addEventListener(U,X.name,function(Q){CU(Q,U,G,K,H)},X.capture)}function CU(U,z,G,K,H){G(function(X){if(Array.isArray(U))for(let Q of U)t(Q,X,z,K,H);else t(U,X,z,K,H)})}function t(U,z,G,K,H){var X=H.getTarget(U);if(X){let Q=FU(G,X,H);D(U,z,Q,K,H)}}function FU(U,z,G){var K=[];while(!G.isEqual(U,z))if(K.unshift(z),z&&G.parentNode(z))z=G.parentNode(z);else return K;return K}function D(U,z,G,K,H){if(!G.length){if(K)console.warn('Event "'+U.type+'" did not find an event handler to dispatch on',z,U);return}else if(G.length>1){if(z.type===2)return;else if(z.type===0){if(!z.child){if(K)throw console.error("VComp has no child property set during event delegation",z),console.error("This means the Component has not been fully mounted, this should never happen"),new Error("VComp has no .child property set during event delegation");return}return D(U,z.child,G,K,H)}else if(z.type===1){if(H.isEqual(z.domRef,G[0])){let X=z.events.captures[U.type];if(X){let Q=X.options;if(Q.preventDefault)U.preventDefault();if(!U.captureStopped)X.runEvent(U,z.domRef);if(Q.stopPropagation)U.captureStopped=!0}G.splice(0,1);for(let Q of z.children)if(H.isEqual(q(Q),G[0]))D(U,Q,G,K,H)}return}}else if(z.type===0){if(z.child)D(U,z.child,G,K,H)}else if(z.type===1){let X=z.events.captures[U.type];if(X&&!U.captureStopped){let Z=X.options;if(H.isEqual(G[0],z.domRef)){if(Z.preventDefault)U.preventDefault();if(X.runEvent(U,G[0]),Z.stopPropagation)U.captureStopped=!0}}let Q=z.events.bubbles[U.type];if(Q&&!U.captureStopped){let Z=Q.options;if(H.isEqual(G[0],z.domRef)){if(Z.preventDefault)U.preventDefault();if(Q.runEvent(U,G[0]),!Z.stopPropagation)e(z.parent,U)}}else if(!U.captureStopped)e(z.parent,U)}}function e(U,z){while(U)switch(U.type){case 2:break;case 1:let G=U.events.bubbles[z.type];if(G){let K=G.options;if(K.preventDefault)z.preventDefault();if(G.runEvent(z,U.domRef),K.stopPropagation)return}U=U.parent;break;case 0:if(!U.eventPropagation)return;U=U.parent;break}}function B(U,z){if(typeof U[0]==="object"){var G=[];for(var K=0;K0?[U[0]]:[];for(var K=1;K{return+z})}function a(U,z,G){return GU(!0,U,z,G)}function GU(U,z,G,K){if(z.type==2){if(G.getTag(z.domRef)!=="#text")console.warn("VText domRef not a TEXT_NODE",z),U=!1;else if(z.text!==G.getTextContent(z.domRef))console.warn("VText node content differs",z),U=!1}else if(z.type===1){if(z.tag.toUpperCase()!==G.getTag(z.domRef).toUpperCase())console.warn("Integrity check failed, tags differ",z.tag.toUpperCase(),G.getTag(z.domRef)),U=!1;if("children"in z&&z.children.length!==G.children(z.domRef).length)console.warn("Integrity check failed, children lengths differ",z,z.children,G.children(z.domRef)),U=!1;for(let H in z.props)if(H==="href"||H==="src"){let X=window.location.origin+"/"+z.props[H],Q=G.getAttribute(z.domRef,H),Z=z.props[H];if(X!==Q&&Z!==Q&&Z+"/"!==Q&&X+"/"!==Q)console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1}else if(H==="height"||H==="width"){if(parseFloat(z.props[H])!==parseFloat(G.getAttribute(z.domRef,H)))console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1}else if(H==="class"||H==="className"){if(z.props[H]!==G.getAttribute(z.domRef,"class"))console.warn("Property class differs",z.props[H],G.getAttribute(z.domRef,"class")),U=!1}else if(z.props[H]!==G.getAttribute(z.domRef,H))console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1;for(let H in z.css)if(H==="color"){if(zU(G.getInlineStyle(z.domRef,H)).toString()!==zU(z.css[H]).toString())console.warn("Style "+H+" differs",z.css[H],G.getInlineStyle(z.domRef,H)),U=!1}else if(z.css[H]!==G.getInlineStyle(z.domRef,H))console.warn("Style "+H+" differs",z.css[H],G.getInlineStyle(z.domRef,H)),U=!1;for(let H of z.children){let X=GU(U,H,G,K);U=U&&X}}return U}function p(U,z,G,K,H){switch(z.type){case 0:if(!p(U,z.child,G,K,H))return!1;break;case 2:if(G.nodeType!==3||z.text.trim()!==G.textContent.trim())return x(U,z,G),!1;z.domRef=G;break;case 1:if(G.nodeType!==1)return x(U,z,G),!1;z.domRef=G,z.children=IU(z.children),n(G,z,H);for(var X=0;X{U.addEventListener(z,G,K)},delegator:(U,z,G,K,H)=>{UU(U,z,G,K,H)},isEqual:(U,z)=>{return U===z},getTarget:(U)=>{return U.target},parentNode:(U)=>{return U.parentNode}},HU={getInlineStyle:(U,z)=>{return U.style[z]},firstChild:(U)=>{return U.firstChild},lastChild:(U)=>{return U.lastChild},getAttribute:(U,z)=>{if(z==="class")return U.className;if(z in U)return U[z];return U.getAttribute(z)},getTag:(U)=>{return U.nodeName},getTextContent:(U)=>{return U.textContent},children:(U)=>{return U.childNodes}},KU={mountComponent:function(U,z,G){return},unmountComponent:function(U){return},modelHydration:function(U){return}},QU={nextSibling:(U)=>{if(U.nextSibling)switch(U.nextSibling.type){case 0:return S(U.nextSibling);default:return U.nextSibling.domRef}return null},createTextNode:(U)=>{return document.createTextNode(U)},createElementNS:(U,z)=>{return document.createElementNS(U,z)},appendChild:(U,z)=>{return U.appendChild(z)},replaceChild:(U,z,G)=>{return U.replaceChild(z,G)},removeChild:(U,z)=>{return U.removeChild(z)},createElement:(U)=>{return document.createElement(U)},addClass:(U,z)=>{if(U)z.classList.add(U)},removeClass:(U,z)=>{if(U)z.classList.remove(U)},insertBefore:(U,z,G)=>{return U.insertBefore(z,G)},swapDOMRefs:(U,z,G)=>{let K=U.nextSibling;G.insertBefore(U,z),G.insertBefore(z,K);return},setInlineStyle:(U,z,G)=>{var K;for(let H in U)if(K=z[H],!K)if(H in G.style)G.style[H]="";else G.style.setProperty(H,"");else if(K!==U[H])if(H in G.style)G.style[H]=K;else G.style.setProperty(H,K);for(let H in z){if(U&&U[H])continue;if(H in G.style)G.style[H]=z[H];else G.style.setProperty(H,z[H])}return},setAttribute:(U,z,G)=>{return U.setAttribute(z,G)},setAttributeNS:(U,z,G,K)=>{return U.setAttributeNS(z,G,K)},removeAttribute:(U,z)=>{return U.removeAttribute(z)},setTextContent:(U,z)=>{U.textContent=z;return},flush:()=>{return},getHead:function(){return document.head},getRoot:function(){return document.body}};globalThis.miso={hydrationContext:HU,eventContext:s,drawingContext:QU,componentContext:KU,diff:A,hydrate:d,version:F,callBlur:I,callFocus:L,callSelect:w,callSetSelectionRange:V,eventJSON:B,fetchCore:O,eventSourceConnect:b,eventSourceClose:T,websocketConnect:P,websocketClose:f,websocketSend:j,updateRef:h,inline:g,typeOf:m,mathRandom:v,getRandomValues:u,splitmix32:y,populateClass:k,integrityCheck:a,delegateEvent:D,delegator:s.delegator,setDrawingContext:function(U){let z=globalThis[U].drawingContext,G=globalThis[U].eventContext;if(!z)console.error('Custom rendering engine ("drawingContext") is not defined at globalThis[name].drawingContext',U);if(!G)console.error('Custom event delegation ("eventContext") is not defined at globalThis[name].eventContext',U);globalThis.miso.drawingContext=z,globalThis.miso.eventContext=G}}; +var F="1.9.0.0";function L(U,z){var G=function(){var K=document.getElementById(U);if(K&&K.focus)K.focus()};z>0?setTimeout(G,z):G()}function I(U,z){var G=function(){var K=document.getElementById(U);if(K&&K.blur)K.blur()};z>0?setTimeout(G,z):G()}function w(U,z){var G=function(){var K=document.getElementById(U);if(K&&typeof K.select==="function")K.select()};z>0?setTimeout(G,z):G()}function V(U,z,G,K){var H=function(){var X=document.getElementById(U);if(X&&typeof X.setSelectionRange==="function")X.setSelectionRange(z,G,"none")};K>0?setTimeout(H,K):H()}function O(U,z,G,K,H,X,Q){var Z={method:z,headers:K};if(G)Z.body=G;let _={},$=null;try{fetch(U,Z).then((Y)=>{$=Y.status;for(let[W,J]of Y.headers)_[W]=J;if(!Y.ok)throw Error(Y.statusText);if(Q=="json")return Y.json();else if(Q=="text")return Y.text();else if(Q==="arrayBuffer")return Y.arrayBuffer();else if(Q==="blob")return Y.blob();else if(Q==="bytes")return Y.bytes();else if(Q==="formData")return Y.formData();else if(Q==="none")return H({error:null,body:null,headers:_,status:$})}).then((Y)=>H({error:null,body:Y,headers:_,status:$})).catch((Y)=>X({error:null,body:Y,headers:_,status:$}))}catch(Y){X({body:null,error:Y.message,headers:_,status:$})}}function P(U,z,G,K,H,X,Q,Z,_){try{let $=new WebSocket(U);return $.onopen=function(){z()},$.onclose=function(Y){G(Y)},$.onerror=function(Y){console.error(Y),Z("WebSocket error received")},$.onmessage=function(Y){if(typeof Y.data==="string")try{if(_){if(K)K(Y.data);return}let W=JSON.parse(Y.data);if(H)H(W)}catch(W){if(_&&K)K(Y.data);else Z(W.message)}else if(Y.data instanceof Blob){if(X)X(Y.data)}else if(Y.data instanceof ArrayBuffer){if(Q)Q(Y.data)}else console.error("Received unknown message type from WebSocket",Y),Z("Unknown message received from WebSocket")},$}catch($){Z($.message)}}function f(U){if(U)U.close(),U=null}function j(U,z){if(z&&U&&U.readyState===WebSocket.OPEN)U.send(z)}function b(U,z,G,K,H,X){try{let Q=new EventSource(U);return Q.onopen=function(){z()},Q.onerror=function(){H("EventSource error received")},Q.onmessage=function(Z){try{if(X){if(G)G(Z.data);return}let _=JSON.parse(Z.data);if(K)K(_)}catch(_){if(X&&G)G(Z.data);else H(_.message)}},Q}catch(Q){H(Q.message)}}function T(U){if(U)U.close(),U=null}function k(U,z){if(!U.classList)U.classList=new Set;for(let G of z)for(let K of G.trim().split(" "))if(K)U.classList.add(K)}function h(U,z){if(!U.parent)return;z.nextSibling=U.nextSibling?null:U.nextSibling,z.parent=U.parent,U.parent.child=z}function g(U,z={}){let G=Object.keys(z),K=Object.values(z);return Function(...G,U)(...K)}function m(U){if(U===null||U===void 0)return 0;if(typeof U==="number")return 1;if(typeof U==="string")return 2;if(typeof U==="boolean")return 3;if(Array.isArray(U))return 4;return 5}function y(U){return function(){U|=0,U=U+2654435769|0;var z=U^U>>>15;return z=Math.imul(z,2246822507),z=z^z>>>13,z=Math.imul(z,3266489909),((z^z>>>16)>>>0)/4294967296}}function u(){let U=new Uint32Array(1);return crypto.getRandomValues(U)[0]}function v(){return Math.random()}function q(U){switch(U.type){case 0:return S(U);default:return U.domRef}}function S(U){if(!U.child)throw Error("'drill' called on an unmounted Component. This should never happen, please make an issue.");switch(U.child.type){case 0:return S(U.child);default:return U.child.domRef}}function l(){return __BACKGROUND__}function A(U,z,G,K){if(!U&&!z)return;else if(!U)NU(z,G,K);else if(!z)o(U,G,K);else if(U.type===2&&z.type===2)YU(U,z,K);else if(U.type===0&&z.type===0){if(z.key===U.key){if(z.child=U.child,z.componentId=U.componentId,U.child)U.child.parent=z;return}i(U,z,G,K)}else if(U.type===1&&z.type===1)if(z.tag===U.tag&&z.key===U.key)z.domRef=U.domRef,n(U,z,K);else i(U,z,G,K);else i(U,z,G,K)}function YU(U,z,G){if(U.text!==z.text)G.setTextContent(U.domRef,z.text);z.domRef=U.domRef;return}function i(U,z,G,K){switch(U.type){case 2:break;default:M(U);break}switch(x(G,1,q(U),z,K),U.type){case 2:break;default:R(U);break}}function o(U,z,G){switch(U.type){case 2:break;default:M(U);break}switch(G.removeChild(z,q(U)),U.type){case 2:break;default:R(U);break}}function R(U){switch(ZU(U),U.type){case 1:for(let z of U.children)if(z.type===1||z.type===0)R(z);break;case 0:if(U.child){if(U.child.type===1||U.child.type===0)R(U.child)}break}}function ZU(U){if(U.type===1&&U.onDestroyed)U.onDestroyed();if(U.type===0)SU(U)}function $U(U){switch(U.type){case 0:break;case 1:if(U.onBeforeDestroyed)U.onBeforeDestroyed();break;default:break}}function M(U){switch($U(U),U.type){case 1:for(let z of U.children){if(z.type===2)continue;M(z)}break;case 0:if(U.child){if(U.child.type===1||U.child.type===0)M(U.child)}break}}function n(U,z,G){WU(U?U.props:{},z.props,z.domRef,z.ns==="svg",G),_U(U?U.classList:null,z.classList,z.domRef,G),qU(U?U.css:{},z.css,z.domRef,G),JU(U?U.children:[],z.children,z.domRef,G),DU(z)}function _U(U,z,G,K){if(!U&&!z)return;if(!U){for(let H of z)K.addClass(H,G);return}if(!z){for(let H of U)K.removeClass(H,G);return}for(let H of U)if(!z.has(H))K.removeClass(H,G);for(let H of z)if(!U.has(H))K.addClass(H,G);return}function WU(U,z,G,K,H){var X;for(let Q in U)if(X=z[Q],X===void 0)if(K||!(Q in G)||Q==="disabled")H.removeAttribute(G,Q);else H.setAttribute(G,Q,"");else{if(X===U[Q]&&Q!=="checked"&&Q!=="value")continue;if(K)if(Q==="href")H.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",X);else H.setAttribute(G,Q,X);else if(Q in G&&!(Q==="list"||Q==="form"))G[Q]=X;else H.setAttribute(G,Q,X)}for(let Q in z){if(U&&U[Q])continue;if(X=z[Q],K)if(Q==="href")H.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",X);else H.setAttribute(G,Q,X);else if(Q in G&&!(Q==="list"||Q==="form"))G[Q]=z[Q];else H.setAttribute(G,Q,X)}}function qU(U,z,G,K){K.setInlineStyle(U,z,G)}function AU(U,z){if(U.length===0||z.length===0)return!1;for(var G=0;GZ&&H>Q)break;if($=z[X],Y=z[Z],J=U[H],W=U[Q],H>Q)A(null,$,G,K),N(G,$,J,K),U.splice(X,0,$),X++;else if(X>Z){_=Q;while(Q>=H)o(U[Q--],G,K);U.splice(H,_-H+1);break}else if(J.key===$.key)A(U[H++],z[X++],G,K);else if(W.key===Y.key)A(U[Q--],z[Z--],G,K);else if(J.key===Y.key&&$.key===W.key)RU(W,J,G,K),CU(U,H,Q),A(U[H++],z[X++],G,K),A(U[Q--],z[Z--],G,K);else if(J.key===Y.key)N(G,J,W.nextSibling,K),U.splice(Q,0,U.splice(H,1)[0]),A(U[Q--],z[Z--],G,K);else if(W.key===$.key)N(G,W,J,K),U.splice(H,0,U.splice(Q,1)[0]),A(U[H++],$,G,K),X++;else{C=!1,_=H;while(_<=Q){if(U[_].key===$.key){C=!0,c=U[_];break}_++}if(C)U.splice(H,0,U.splice(_,1)[0]),A(U[H++],$,G,K),N(G,c,U[H],K),X++;else x(G,2,q(J),$,K),U.splice(H++,0,$),X++,Q++}}}function CU(U,z,G){let K=U[z];U[z]=U[G],U[G]=K}function zU(U,z,G,K,H){for(let X of z)H.addEventListener(U,X.name,function(Q){FU(Q,U,G,K,H)},X.capture)}function FU(U,z,G,K,H){G(function(X){if(Array.isArray(U))for(let Q of U)e(Q,X,z,K,H);else e(U,X,z,K,H)})}function e(U,z,G,K,H){var X=H.getTarget(U);if(X){let Q=LU(G,X,H);D(U,z,Q,K,H)}}function LU(U,z,G){var K=[];while(!G.isEqual(U,z))if(K.unshift(z),z&&G.parentNode(z))z=G.parentNode(z);else return K;return K}function D(U,z,G,K,H){if(!G.length){if(K)console.warn('Event "'+U.type+'" did not find an event handler to dispatch on',z,U);return}else if(G.length>1){if(z.type===2)return;else if(z.type===0){if(!z.child){if(K)throw console.error("VComp has no child property set during event delegation",z),console.error("This means the Component has not been fully mounted, this should never happen"),Error("VComp has no .child property set during event delegation");return}return D(U,z.child,G,K,H)}else if(z.type===1){if(H.isEqual(z.domRef,G[0])){let X=z.events.captures[U.type];if(X){let Q=X.options;if(Q.preventDefault)U.preventDefault();if(!U.captureStopped)X.runEvent(U,z.domRef);if(Q.stopPropagation)U.captureStopped=!0}G.splice(0,1);for(let Q of z.children)if(H.isEqual(q(Q),G[0]))D(U,Q,G,K,H)}return}}else if(z.type===0){if(z.child)D(U,z.child,G,K,H)}else if(z.type===1){let X=z.events.captures[U.type];if(X&&!U.captureStopped){let Z=X.options;if(H.isEqual(G[0],z.domRef)){if(Z.preventDefault)U.preventDefault();if(X.runEvent(U,G[0]),Z.stopPropagation)U.captureStopped=!0}}let Q=z.events.bubbles[U.type];if(Q&&!U.captureStopped){let Z=Q.options;if(H.isEqual(G[0],z.domRef)){if(Z.preventDefault)U.preventDefault();if(Q.runEvent(U,G[0]),!Z.stopPropagation)UU(z.parent,U)}}else if(!U.captureStopped)UU(z.parent,U)}}function UU(U,z){while(U)switch(U.type){case 2:break;case 1:let G=U.events.bubbles[z.type];if(G){let K=G.options;if(K.preventDefault)z.preventDefault();if(G.runEvent(z,U.domRef),K.stopPropagation)return}U=U.parent;break;case 0:if(!U.eventPropagation)return;U=U.parent;break}}function B(U,z){if(typeof U[0]==="object"){var G=[];for(var K=0;K0?[U[0]]:[];for(var K=1;K{return+z})}function s(U,z,G){return HU(!0,U,z,G)}function HU(U,z,G,K){if(z.type==2){if(G.getTag(z.domRef)!=="#text")console.warn("VText domRef not a TEXT_NODE",z),U=!1;else if(z.text!==G.getTextContent(z.domRef))console.warn("VText node content differs",z),U=!1}else if(z.type===1){if(z.tag.toUpperCase()!==G.getTag(z.domRef).toUpperCase())console.warn("Integrity check failed, tags differ",z.tag.toUpperCase(),G.getTag(z.domRef)),U=!1;if("children"in z&&z.children.length!==G.children(z.domRef).length)console.warn("Integrity check failed, children lengths differ",z,z.children,G.children(z.domRef)),U=!1;for(let H in z.props)if(H==="href"||H==="src"){let X=window.location.origin+"/"+z.props[H],Q=G.getAttribute(z.domRef,H),Z=z.props[H];if(X!==Q&&Z!==Q&&Z+"/"!==Q&&X+"/"!==Q)console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1}else if(H==="height"||H==="width"){if(parseFloat(z.props[H])!==parseFloat(G.getAttribute(z.domRef,H)))console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1}else if(H==="class"||H==="className"){if(z.props[H]!==G.getAttribute(z.domRef,"class"))console.warn("Property class differs",z.props[H],G.getAttribute(z.domRef,"class")),U=!1}else if(z.props[H]!==G.getAttribute(z.domRef,H))console.warn("Property "+H+" differs",z.props[H],G.getAttribute(z.domRef,H)),U=!1;for(let H in z.css)if(H==="color"){if(GU(G.getInlineStyle(z.domRef,H)).toString()!==GU(z.css[H]).toString())console.warn("Style "+H+" differs",z.css[H],G.getInlineStyle(z.domRef,H)),U=!1}else if(z.css[H]!==G.getInlineStyle(z.domRef,H))console.warn("Style "+H+" differs",z.css[H],G.getInlineStyle(z.domRef,H)),U=!1;for(let H of z.children){let X=HU(U,H,G,K);U=U&&X}}return U}function d(U,z,G,K,H){switch(z.type){case 0:if(!d(U,z.child,G,K,H))return!1;break;case 2:if(G.nodeType!==3||z.text.trim()!==G.textContent.trim())return p(U,z,G),!1;z.domRef=G;break;case 1:if(G.nodeType!==1)return p(U,z,G),!1;z.domRef=G,z.children=wU(z.children),t(G,z,H);for(var X=0;X{U.addEventListener(z,G,K)},delegator:(U,z,G,K,H)=>{zU(U,z,G,K,H)},isEqual:(U,z)=>{return U===z},getTarget:(U)=>{return U.target},parentNode:(U)=>{return U.parentNode}},KU={getInlineStyle:(U,z)=>{return U.style[z]},firstChild:(U)=>{return U.firstChild},lastChild:(U)=>{return U.lastChild},getAttribute:(U,z)=>{if(z==="class")return U.className;if(z in U)return U[z];return U.getAttribute(z)},getTag:(U)=>{return U.nodeName},getTextContent:(U)=>{return U.textContent},children:(U)=>{return U.childNodes}},QU={mountComponent:function(U,z,G){return},unmountComponent:function(U){return},modelHydration:function(U){return}},XU={nextSibling:(U)=>{if(U.nextSibling)switch(U.nextSibling.type){case 0:return S(U.nextSibling);default:return U.nextSibling.domRef}return null},createTextNode:(U)=>{return document.createTextNode(U)},createElementNS:(U,z)=>{return document.createElementNS(U,z)},appendChild:(U,z)=>{return U.appendChild(z)},replaceChild:(U,z,G)=>{return U.replaceChild(z,G)},removeChild:(U,z)=>{return U.removeChild(z)},createElement:(U)=>{return document.createElement(U)},addClass:(U,z)=>{if(U)z.classList.add(U)},removeClass:(U,z)=>{if(U)z.classList.remove(U)},insertBefore:(U,z,G)=>{return U.insertBefore(z,G)},swapDOMRefs:(U,z,G)=>{let K=U.nextSibling;G.insertBefore(U,z),G.insertBefore(z,K);return},setInlineStyle:(U,z,G)=>{var K;for(let H in U)if(K=z[H],!K)if(H in G.style)G.style[H]="";else G.style.setProperty(H,"");else if(K!==U[H])if(H in G.style)G.style[H]=K;else G.style.setProperty(H,K);for(let H in z){if(U&&U[H])continue;if(H in G.style)G.style[H]=z[H];else G.style.setProperty(H,z[H])}return},setAttribute:(U,z,G)=>{return U.setAttribute(z,G)},setAttributeNS:(U,z,G,K)=>{return U.setAttributeNS(z,G,K)},removeAttribute:(U,z)=>{return U.removeAttribute(z)},setTextContent:(U,z)=>{U.textContent=z;return},flush:()=>{return},getHead:function(){return document.head},getRoot:function(){return document.body}};globalThis.miso={bts:l,hydrationContext:KU,eventContext:r,drawingContext:XU,componentContext:QU,diff:A,hydrate:a,version:F,callBlur:I,callFocus:L,callSelect:w,callSetSelectionRange:V,eventJSON:B,fetchCore:O,eventSourceConnect:b,eventSourceClose:T,websocketConnect:P,websocketClose:f,websocketSend:j,updateRef:h,inline:g,typeOf:m,mathRandom:v,getRandomValues:u,splitmix32:y,populateClass:k,integrityCheck:s,delegateEvent:D,delegator:r.delegator,setDrawingContext:function(U){let z=globalThis[U].drawingContext,G=globalThis[U].eventContext;if(!z)console.error('Custom rendering engine ("drawingContext") is not defined at globalThis[name].drawingContext',U);if(!G)console.error('Custom event delegation ("eventContext") is not defined at globalThis[name].eventContext',U);globalThis.miso.drawingContext=z,globalThis.miso.eventContext=G}}; diff --git a/package.json b/package.json index f8c963637..a6769219c 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ }, "homepage": "https://haskell-miso.org", "devDependencies": { - "@happy-dom/global-registrator": "^17.5.6", + "@happy-dom/global-registrator": "latest", "prettier": "3.5.3", "@types/bun": "latest" }, diff --git a/src/Miso.hs b/src/Miso.hs index 8017c882e..a6c992a46 100644 --- a/src/Miso.hs +++ b/src/Miso.hs @@ -4,6 +4,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- {-# OPTIONS_GHC -Wno-duplicate-exports #-} ----------------------------------------------------------------------------- @@ -201,5 +202,17 @@ withJS action = void $ do #ifdef WASM $(evalFile MISO_JS_PATH) #endif +#ifdef GHCJS_NEW + FFI.consoleLog "withJS" + onBTS <- FFI.bts + if onBTS + then do + FFI.consoleLog "on bts" + void action + else do + FFI.consoleLog "on mts, bailing" + pure () +#else action +#endif ----------------------------------------------------------------------------- diff --git a/src/Miso/FFI.hs b/src/Miso/FFI.hs index 3fba4dcb8..c23a772d3 100644 --- a/src/Miso/FFI.hs +++ b/src/Miso/FFI.hs @@ -101,6 +101,8 @@ module Miso.FFI , splitmix32 -- ** Math.random() , mathRandom + -- ** Native helpers + , bts ) where ----------------------------------------------------------------------------- import Miso.FFI.Internal diff --git a/src/Miso/FFI/Internal.hs b/src/Miso/FFI/Internal.hs index 3e9a07100..aa97f5e9c 100644 --- a/src/Miso/FFI/Internal.hs +++ b/src/Miso/FFI/Internal.hs @@ -148,6 +148,8 @@ module Miso.FFI.Internal , mathRandom -- * Crypto , getRandomValue + -- * Native + , bts ) where ----------------------------------------------------------------------------- import Control.Monad (void, forM_, (<=<), when) @@ -460,14 +462,13 @@ diff (Object a) (Object b) c = do delegator :: JSVal -> JSVal -> Bool -> IO JSVal -> IO () delegator mountPoint events debug getVTree = do ctx <- getEventContext + d <- toJSVal debug #ifdef WASM cb <- asyncCallback1 $ \continuation -> void (call continuation global =<< getVTree) #else cb <- syncCallback1 $ \continuation -> void (call continuation global =<< getVTree) #endif - d <- toJSVal debug - moduleMiso <- jsg "miso" - void $ moduleMiso # "delegator" $ [mountPoint,events,cb,d,ctx] + void $ ctx # "delegator" $ [mountPoint,events,cb,d,ctx] ----------------------------------------------------------------------------- -- | Copies DOM pointers into virtual dom entry point into isomorphic javascript -- @@ -1037,3 +1038,6 @@ getRandomValue :: IO Double getRandomValue = fromJSValUnchecked =<< do jsg "miso" # "getRandomValues" $ () ----------------------------------------------------------------------------- +bts :: IO Bool +bts = fromJSValUnchecked =<< do jsg "miso" # "bts" $ () +----------------------------------------------------------------------------- diff --git a/src/Miso/Runtime.hs b/src/Miso/Runtime.hs index e288dd83b..cb96c1555 100644 --- a/src/Miso/Runtime.hs +++ b/src/Miso/Runtime.hs @@ -186,6 +186,7 @@ initialize events _componentParentId hydrate isRoot comp@Component {..} getCompo Diff.diff (Just oldVTree) (Just newVTree) _componentDOMRef FFI.updateRef oldVTree newVTree liftIO (atomicWriteIORef _componentVTree newVTree) + FFI.flush let _componentApplyActions = \(actions :: [action]) model_ comps -> do let info = ComponentInfo _componentId _componentParentId _componentDOMRef diff --git a/ts/index.ts b/ts/index.ts index fe4255ab8..a3d71078f 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -22,6 +22,7 @@ import { getRandomValues, splitmix32, delegateEvent, + bts, } from './miso'; import { @@ -33,6 +34,7 @@ import { /* export globally */ globalThis['miso'] = { + bts, hydrationContext, eventContext, drawingContext, diff --git a/ts/miso.ts b/ts/miso.ts index 4ea035797..455314cb2 100644 --- a/ts/miso.ts +++ b/ts/miso.ts @@ -18,6 +18,7 @@ import { updateRef, inline, typeOf, + bts, mathRandom, getRandomValues, splitmix32, @@ -109,6 +110,7 @@ export { splitmix32, delegateEvent, getDOMRef, + bts, /* Types */ VTree, diff --git a/ts/miso/util.ts b/ts/miso/util.ts index f73278dd1..337b8bbf8 100644 --- a/ts/miso/util.ts +++ b/ts/miso/util.ts @@ -298,3 +298,7 @@ export function drill(c: VComp): T { return c.child.domRef; } } + +export function bts () : boolean { + return __BACKGROUND__; +}