mayu-live 0.0.0 → 0.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9849accde2e14e4ac0417842d39822002b8d7954f89bf30da438df1905ea6de
4
- data.tar.gz: 79467e122b749a39f8a89842beaf6883bf4cee325bf0499b55553c897dc0157f
3
+ metadata.gz: 735436aabe452e5ddc5aa389289914f6c61a291e4dd0181c8f73623dd0cb4de0
4
+ data.tar.gz: 7fc97738ce43ffbec5914ec9f20424431b09a2dac0f3ff17f2ff77eec0d380ef
5
5
  SHA512:
6
- metadata.gz: 5bd6340a3e2e52dc204c3f134c99a72aafebc351b0b33c6de6ef7ca2ab5adb3d4cae274bdcf3c7021a28d4a74fa28b606d6e9dff1dd4c7c328df89dd5e80eca0
7
- data.tar.gz: c7d5f2a37de7c56db4eb57ff519a4ca635c2ad64357b30c75007d1659f8717b2776d24021e092b699e350b1d911e6d03207bc8f193392f46113e03eada3f0668
6
+ metadata.gz: f72c568709d9cc26eb9b4adfa9cdf54d76dbf7b222007cfc677761be86d80be6fca98fd86ff913296b17834b37442580f03503c838bb92d7f7f4e518853df5b2
7
+ data.tar.gz: cd4ab2c5a1db6ef2492ebf3e1518d9b1c314ab1a0c844e5c8551c8a830c0f15dd0282dcbef01238b76e65520378562dc5db2189e8dd695fd00518eb39acdf08e
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # <img alt="Mayu Live" width="337" src="https://user-images.githubusercontent.com/41148/192179194-f44aed92-74a3-4b59-a25e-bf2a8d313796.png">
2
2
 
3
- [![Ruby Workflow Status](https://img.shields.io/github/actions/workflow/status/mayu-live/framework/.github/workflows/ruby.yml?branch=main&label=ruby&style=flat-square)](https://github.com/mayu-live/framework/actions/workflows/ruby.yml)
4
- [![Node Workflow Status](https://img.shields.io/github/actions/workflow/status/mayu-live/framework/.github/workflows/node.js.yml?branch=main&label=js&style=flat-square)](https://github.com/mayu-live/framework/actions/workflows/node.js.yml)
3
+ [![Tests](https://img.shields.io/github/actions/workflow/status/mayu-live/framework/.github/workflows/test.yml?branch=main&label=Tests&style=flat-square)](https://github.com/mayu-live/framework/actions/workflows/test.yml)
4
+ [![Release](https://img.shields.io/github/v/release/mayu-live/framework?sort=semver&style=flat-square)](https://github.com/mayu-live/framework/releases)
5
5
  [![GitHub commit activity](https://img.shields.io/github/commit-activity/w/mayu-live/framework/main?style=flat-square)](https://github.com/mayu-live/framework/commits)
6
6
  [![License AGPL-3.0](https://img.shields.io/github/license/mayu-live/framework?style=flat-square)](https://github.com/mayu-live/framework/blob/main/COPYING) ![Status: Experimental](https://img.shields.io/badge/status-experimental-critical?style=flat-square)
7
7
 
@@ -56,7 +56,7 @@ having to configure anything!
56
56
  - [100% server side](#100-server-side)
57
57
  - [100% async](#100-async)
58
58
  - [Components](#components)
59
- - [CSS modules](#css-modules)
59
+ - [Scoped CSS](#scoped-css)
60
60
  - [State management](#state-management)
61
61
  - [Path based routing](#path-based-routing)
62
62
  - [Hot reloading](#hot-reloading)
@@ -217,7 +217,7 @@ rendering libraries. This is the same thing, but in Ruby.
217
217
  All class names and element names are given an unique name,
218
218
  inspired by [CSS Modules](https://github.com/css-modules/css-modules).
219
219
 
220
- Class names are applied automatically by Haml.
220
+ Class names are applied automatically.
221
221
 
222
222
  ### `app/components/Example.haml`
223
223
 
@@ -1,3 +1,3 @@
1
1
  {
2
- "main": "main-4b49dbc4.js"
2
+ "main": "main-8506b35d.js"
3
3
  }
@@ -1 +1 @@
1
- var e,t,n,r=4294967295;function o(e,t){return 4294967296*e.getInt32(t)+e.getUint32(t+4)}var i=("undefined"==typeof process||"never"!==(null===(e=null===process||void 0===process?void 0:process.env)||void 0===e?void 0:e.TEXT_ENCODING))&&"undefined"!=typeof TextEncoder&&"undefined"!=typeof TextDecoder,s=i?new TextEncoder:void 0;i&&"undefined"!=typeof process&&(null===(t=null===process||void 0===process?void 0:process.env)||void 0===t||t.TEXT_ENCODING),null==s||s.encodeInto;function a(e,t,n){for(var r=t,o=r+n,i=[],s="";r<o;){var a=e[r++];if(0==(128&a))i.push(a);else if(192==(224&a)){var c=63&e[r++];i.push((31&a)<<6|c)}else if(224==(240&a)){c=63&e[r++];var u=63&e[r++];i.push((31&a)<<12|c<<6|u)}else if(240==(248&a)){var h=(7&a)<<18|(c=63&e[r++])<<12|(u=63&e[r++])<<6|63&e[r++];h>65535&&(h-=65536,i.push(h>>>10&1023|55296),h=56320|1023&h),i.push(h)}else i.push(a);i.length>=4096&&(s+=String.fromCharCode.apply(String,i),i.length=0)}return i.length>0&&(s+=String.fromCharCode.apply(String,i)),s}var c=i?new TextDecoder:null,u=i?"undefined"!=typeof process&&"force"!==(null===(n=null===process||void 0===process?void 0:process.env)||void 0===n?void 0:n.TEXT_DECODER)?200:0:r;var h,d=function(e,t){this.type=e,this.data=t},l=(h=function(e,t){return h=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},h(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}h(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),f=function(e){function t(n){var r=e.call(this,n)||this,o=Object.create(t.prototype);return Object.setPrototypeOf(r,o),Object.defineProperty(r,"name",{configurable:!0,enumerable:!1,value:t.name}),r}return l(t,e),t}(Error);function p(e){var t=e.sec,n=e.nsec;if(t>=0&&n>=0&&t<=17179869183){if(0===n&&t<=4294967295){var r=new Uint8Array(4);return(s=new DataView(r.buffer)).setUint32(0,t),r}var o=t/4294967296,i=4294967295&t;r=new Uint8Array(8);return(s=new DataView(r.buffer)).setUint32(0,n<<2|3&o),s.setUint32(4,i),r}var s;r=new Uint8Array(12);return(s=new DataView(r.buffer)).setUint32(0,n),function(e,t,n){var r=Math.floor(n/4294967296),o=n;e.setUint32(t,r),e.setUint32(t+4,o)}(s,4,t),r}var y={type:-1,encode:function(e){var t,n,r,o;return e instanceof Date?p((t=e.getTime(),n=Math.floor(t/1e3),r=1e6*(t-1e3*n),o=Math.floor(r/1e9),{sec:n+o,nsec:r-1e9*o})):null},decode:function(e){var t=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:t.getUint32(0),nsec:0};case 8:var n=t.getUint32(0);return{sec:4294967296*(3&n)+t.getUint32(4),nsec:n>>>2};case 12:return{sec:o(t,4),nsec:t.getUint32(0)};default:throw new f("Unrecognized data size for timestamp (expected 4, 8, or 12): ".concat(e.length))}}(e);return new Date(1e3*t.sec+t.nsec/1e6)}},m=function(){function e(){this.builtInEncoders=[],this.builtInDecoders=[],this.encoders=[],this.decoders=[],this.register(y)}return e.prototype.register=function(e){var t=e.type,n=e.encode,r=e.decode;if(t>=0)this.encoders[t]=n,this.decoders[t]=r;else{var o=1+t;this.builtInEncoders[o]=n,this.builtInDecoders[o]=r}},e.prototype.tryToEncode=function(e,t){for(var n=0;n<this.builtInEncoders.length;n++){if(null!=(r=this.builtInEncoders[n]))if(null!=(o=r(e,t)))return new d(-1-n,o)}for(n=0;n<this.encoders.length;n++){var r,o;if(null!=(r=this.encoders[n]))if(null!=(o=r(e,t)))return new d(n,o)}return e instanceof d?e:null},e.prototype.decode=function(e,t,n){var r=t<0?this.builtInDecoders[-1-t]:this.decoders[t];return r?r(e,t,n):new d(t,e)},e.defaultCodec=new e,e}();function g(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?new Uint8Array(e):Uint8Array.from(e)}function v(e){return"".concat(e<0?"-":"","0x").concat(Math.abs(e).toString(16).padStart(2,"0"))}var b,w=function(){function e(e,t){void 0===e&&(e=16),void 0===t&&(t=16),this.maxKeyLength=e,this.maxLengthPerKey=t,this.hit=0,this.miss=0,this.caches=[];for(var n=0;n<this.maxKeyLength;n++)this.caches.push([])}return e.prototype.canBeCached=function(e){return e>0&&e<=this.maxKeyLength},e.prototype.find=function(e,t,n){e:for(var r=0,o=this.caches[n-1];r<o.length;r++){for(var i=o[r],s=i.bytes,a=0;a<n;a++)if(s[a]!==e[t+a])continue e;return i.str}return null},e.prototype.store=function(e,t){var n=this.caches[e.length-1],r={bytes:e,str:t};n.length>=this.maxLengthPerKey?n[Math.random()*n.length|0]=r:n.push(r)},e.prototype.decode=function(e,t,n){var r=this.find(e,t,n);if(null!=r)return this.hit++,r;this.miss++;var o=a(e,t,n),i=Uint8Array.prototype.slice.call(e,t,t+n);return this.store(i,o),o},e}(),x=function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},E=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){s.label=i[1];break}if(6===i[0]&&s.label<o[1]){s.label=o[1],o=i;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(i);break}o[2]&&s.ops.pop(),s.trys.pop();continue}i=t.call(e,s)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},S=function(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e="function"==typeof __values?__values(e):e[Symbol.iterator](),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}},T=function(e){return this instanceof T?(this.v=e,this):new T(e)},U=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r={},s("next"),s("throw"),s("return"),r[Symbol.asyncIterator]=function(){return this},r;function s(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){i.push([e,t,n,r])>1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof T?Promise.resolve(n.value.v).then(c,u):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function u(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}},k=new DataView(new ArrayBuffer(0)),A=new Uint8Array(k.buffer),I=function(){try{k.getInt8(0)}catch(e){return e.constructor}throw new Error("never reached")}(),_=new I("Insufficient data"),L=new w,M=function(){function e(e,t,n,o,i,s,a,c){void 0===e&&(e=m.defaultCodec),void 0===t&&(t=void 0),void 0===n&&(n=r),void 0===o&&(o=r),void 0===i&&(i=r),void 0===s&&(s=r),void 0===a&&(a=r),void 0===c&&(c=L),this.extensionCodec=e,this.context=t,this.maxStrLength=n,this.maxBinLength=o,this.maxArrayLength=i,this.maxMapLength=s,this.maxExtLength=a,this.keyDecoder=c,this.totalPos=0,this.pos=0,this.view=k,this.bytes=A,this.headByte=-1,this.stack=[]}return e.prototype.reinitializeState=function(){this.totalPos=0,this.headByte=-1,this.stack.length=0},e.prototype.setBuffer=function(e){this.bytes=g(e),this.view=function(e){if(e instanceof ArrayBuffer)return new DataView(e);var t=g(e);return new DataView(t.buffer,t.byteOffset,t.byteLength)}(this.bytes),this.pos=0},e.prototype.appendBuffer=function(e){if(-1!==this.headByte||this.hasRemaining(1)){var t=this.bytes.subarray(this.pos),n=g(e),r=new Uint8Array(t.length+n.length);r.set(t),r.set(n,t.length),this.setBuffer(r)}else this.setBuffer(e)},e.prototype.hasRemaining=function(e){return this.view.byteLength-this.pos>=e},e.prototype.createExtraByteError=function(e){var t=this.view,n=this.pos;return new RangeError("Extra ".concat(t.byteLength-n," of ").concat(t.byteLength," byte(s) found at buffer[").concat(e,"]"))},e.prototype.decode=function(e){this.reinitializeState(),this.setBuffer(e);var t=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return t},e.prototype.decodeMulti=function(e){return E(this,(function(t){switch(t.label){case 0:this.reinitializeState(),this.setBuffer(e),t.label=1;case 1:return this.hasRemaining(1)?[4,this.doDecodeSync()]:[3,3];case 2:return t.sent(),[3,1];case 3:return[2]}}))},e.prototype.decodeAsync=function(e){var t,n,r,o;return x(this,void 0,void 0,(function(){var i,s,a,c,u,h,d,l;return E(this,(function(f){switch(f.label){case 0:i=!1,f.label=1;case 1:f.trys.push([1,6,7,12]),t=S(e),f.label=2;case 2:return[4,t.next()];case 3:if((n=f.sent()).done)return[3,5];if(a=n.value,i)throw this.createExtraByteError(this.totalPos);this.appendBuffer(a);try{s=this.doDecodeSync(),i=!0}catch(e){if(!(e instanceof I))throw e}this.totalPos+=this.pos,f.label=4;case 4:return[3,2];case 5:return[3,12];case 6:return c=f.sent(),r={error:c},[3,12];case 7:return f.trys.push([7,,10,11]),n&&!n.done&&(o=t.return)?[4,o.call(t)]:[3,9];case 8:f.sent(),f.label=9;case 9:return[3,11];case 10:if(r)throw r.error;return[7];case 11:return[7];case 12:if(i){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return[2,s]}throw h=(u=this).headByte,d=u.pos,l=u.totalPos,new RangeError("Insufficient data in parsing ".concat(v(h)," at ").concat(l," (").concat(d," in the current buffer)"))}}))}))},e.prototype.decodeArrayStream=function(e){return this.decodeMultiAsync(e,!0)},e.prototype.decodeStream=function(e){return this.decodeMultiAsync(e,!1)},e.prototype.decodeMultiAsync=function(e,t){return U(this,arguments,(function(){var n,r,o,i,s,a,c,u,h;return E(this,(function(d){switch(d.label){case 0:n=t,r=-1,d.label=1;case 1:d.trys.push([1,13,14,19]),o=S(e),d.label=2;case 2:return[4,T(o.next())];case 3:if((i=d.sent()).done)return[3,12];if(s=i.value,t&&0===r)throw this.createExtraByteError(this.totalPos);this.appendBuffer(s),n&&(r=this.readArraySize(),n=!1,this.complete()),d.label=4;case 4:d.trys.push([4,9,,10]),d.label=5;case 5:return[4,T(this.doDecodeSync())];case 6:return[4,d.sent()];case 7:return d.sent(),0==--r?[3,8]:[3,5];case 8:return[3,10];case 9:if(!((a=d.sent())instanceof I))throw a;return[3,10];case 10:this.totalPos+=this.pos,d.label=11;case 11:return[3,2];case 12:return[3,19];case 13:return c=d.sent(),u={error:c},[3,19];case 14:return d.trys.push([14,,17,18]),i&&!i.done&&(h=o.return)?[4,T(h.call(o))]:[3,16];case 15:d.sent(),d.label=16;case 16:return[3,18];case 17:if(u)throw u.error;return[7];case 18:return[7];case 19:return[2]}}))}))},e.prototype.doDecodeSync=function(){e:for(;;){var e=this.readHeadByte(),t=void 0;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){if(0!==(r=e-128)){this.pushMapState(r),this.complete();continue e}t={}}else if(e<160){if(0!==(r=e-144)){this.pushArrayState(r),this.complete();continue e}t=[]}else{var n=e-160;t=this.decodeUtf8String(n,0)}else if(192===e)t=null;else if(194===e)t=!1;else if(195===e)t=!0;else if(202===e)t=this.readF32();else if(203===e)t=this.readF64();else if(204===e)t=this.readU8();else if(205===e)t=this.readU16();else if(206===e)t=this.readU32();else if(207===e)t=this.readU64();else if(208===e)t=this.readI8();else if(209===e)t=this.readI16();else if(210===e)t=this.readI32();else if(211===e)t=this.readI64();else if(217===e){n=this.lookU8();t=this.decodeUtf8String(n,1)}else if(218===e){n=this.lookU16();t=this.decodeUtf8String(n,2)}else if(219===e){n=this.lookU32();t=this.decodeUtf8String(n,4)}else if(220===e){if(0!==(r=this.readU16())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(221===e){if(0!==(r=this.readU32())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(222===e){if(0!==(r=this.readU16())){this.pushMapState(r),this.complete();continue e}t={}}else if(223===e){if(0!==(r=this.readU32())){this.pushMapState(r),this.complete();continue e}t={}}else if(196===e){var r=this.lookU8();t=this.decodeBinary(r,1)}else if(197===e){r=this.lookU16();t=this.decodeBinary(r,2)}else if(198===e){r=this.lookU32();t=this.decodeBinary(r,4)}else if(212===e)t=this.decodeExtension(1,0);else if(213===e)t=this.decodeExtension(2,0);else if(214===e)t=this.decodeExtension(4,0);else if(215===e)t=this.decodeExtension(8,0);else if(216===e)t=this.decodeExtension(16,0);else if(199===e){r=this.lookU8();t=this.decodeExtension(r,1)}else if(200===e){r=this.lookU16();t=this.decodeExtension(r,2)}else{if(201!==e)throw new f("Unrecognized type byte: ".concat(v(e)));r=this.lookU32();t=this.decodeExtension(r,4)}this.complete();for(var o=this.stack;o.length>0;){var i=o[o.length-1];if(0===i.type){if(i.array[i.position]=t,i.position++,i.position!==i.size)continue e;o.pop(),t=i.array}else{if(1===i.type){if(s=void 0,"string"!==(s=typeof t)&&"number"!==s)throw new f("The type of key must be string or number but "+typeof t);if("__proto__"===t)throw new f("The key __proto__ is not allowed");i.key=t,i.type=2;continue e}if(i.map[i.key]=t,i.readCount++,i.readCount!==i.size){i.key=null,i.type=1;continue e}o.pop(),t=i.map}}return t}var s},e.prototype.readHeadByte=function(){return-1===this.headByte&&(this.headByte=this.readU8()),this.headByte},e.prototype.complete=function(){this.headByte=-1},e.prototype.readArraySize=function(){var e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:if(e<160)return e-144;throw new f("Unrecognized array type byte: ".concat(v(e)))}},e.prototype.pushMapState=function(e){if(e>this.maxMapLength)throw new f("Max length exceeded: map length (".concat(e,") > maxMapLengthLength (").concat(this.maxMapLength,")"));this.stack.push({type:1,size:e,key:null,readCount:0,map:{}})},e.prototype.pushArrayState=function(e){if(e>this.maxArrayLength)throw new f("Max length exceeded: array length (".concat(e,") > maxArrayLength (").concat(this.maxArrayLength,")"));this.stack.push({type:0,size:e,array:new Array(e),position:0})},e.prototype.decodeUtf8String=function(e,t){var n;if(e>this.maxStrLength)throw new f("Max length exceeded: UTF-8 byte length (".concat(e,") > maxStrLength (").concat(this.maxStrLength,")"));if(this.bytes.byteLength<this.pos+t+e)throw _;var r,o=this.pos+t;return r=this.stateIsMapKey()&&(null===(n=this.keyDecoder)||void 0===n?void 0:n.canBeCached(e))?this.keyDecoder.decode(this.bytes,o,e):e>u?function(e,t,n){var r=e.subarray(t,t+n);return c.decode(r)}(this.bytes,o,e):a(this.bytes,o,e),this.pos+=t+e,r},e.prototype.stateIsMapKey=function(){return this.stack.length>0&&1===this.stack[this.stack.length-1].type},e.prototype.decodeBinary=function(e,t){if(e>this.maxBinLength)throw new f("Max length exceeded: bin length (".concat(e,") > maxBinLength (").concat(this.maxBinLength,")"));if(!this.hasRemaining(e+t))throw _;var n=this.pos+t,r=this.bytes.subarray(n,n+e);return this.pos+=t+e,r},e.prototype.decodeExtension=function(e,t){if(e>this.maxExtLength)throw new f("Max length exceeded: ext length (".concat(e,") > maxExtLength (").concat(this.maxExtLength,")"));var n=this.view.getInt8(this.pos+t),r=this.decodeBinary(e,t+1);return this.extensionCodec.decode(r,n,this.context)},e.prototype.lookU8=function(){return this.view.getUint8(this.pos)},e.prototype.lookU16=function(){return this.view.getUint16(this.pos)},e.prototype.lookU32=function(){return this.view.getUint32(this.pos)},e.prototype.readU8=function(){var e=this.view.getUint8(this.pos);return this.pos++,e},e.prototype.readI8=function(){var e=this.view.getInt8(this.pos);return this.pos++,e},e.prototype.readU16=function(){var e=this.view.getUint16(this.pos);return this.pos+=2,e},e.prototype.readI16=function(){var e=this.view.getInt16(this.pos);return this.pos+=2,e},e.prototype.readU32=function(){var e=this.view.getUint32(this.pos);return this.pos+=4,e},e.prototype.readI32=function(){var e=this.view.getInt32(this.pos);return this.pos+=4,e},e.prototype.readU64=function(){var e,t,n=(e=this.view,t=this.pos,4294967296*e.getUint32(t)+e.getUint32(t+4));return this.pos+=8,n},e.prototype.readI64=function(){var e=o(this.view,this.pos);return this.pos+=8,e},e.prototype.readF32=function(){var e=this.view.getFloat32(this.pos);return this.pos+=4,e},e.prototype.readF64=function(){var e=this.view.getFloat64(this.pos);return this.pos+=8,e},e}(),C={},D=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){s.label=i[1];break}if(6===i[0]&&s.label<o[1]){s.label=o[1],o=i;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(i);break}o[2]&&s.ops.pop(),s.trys.pop();continue}i=t.call(e,s)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},N=function(e){return this instanceof N?(this.v=e,this):new N(e)},B=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r={},s("next"),s("throw"),s("return"),r[Symbol.asyncIterator]=function(){return this},r;function s(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){i.push([e,t,n,r])>1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof N?Promise.resolve(n.value.v).then(c,u):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function u(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}};function O(e){if(null==e)throw new Error("Assertion Failure: value must not be null nor undefined")}function P(e){return null!=e[Symbol.asyncIterator]?e:function(e){return B(this,arguments,(function(){var t,n,r,o;return D(this,(function(i){switch(i.label){case 0:t=e.getReader(),i.label=1;case 1:i.trys.push([1,,9,10]),i.label=2;case 2:return[4,N(t.read())];case 3:return n=i.sent(),r=n.done,o=n.value,r?[4,N(void 0)]:[3,5];case 4:return[2,i.sent()];case 5:return O(o),[4,N(o)];case 6:return[4,i.sent()];case 7:return i.sent(),[3,2];case 8:return[3,10];case 9:return t.releaseLock(),[7];case 10:return[2]}}))}))}(e)}function $(e,t){void 0===t&&(t=C);var n=P(e);return new M(t.extensionCodec,t.context,t.maxStrLength,t.maxBinLength,t.maxArrayLength,t.maxMapLength,t.maxExtLength).decodeStream(n)}async function j(e=1e3){return new Promise((t=>{setTimeout(t,e)}))}class R extends Error{}async function F(e){let t=0;for(;;)try{return await e()}catch(e){if(e instanceof R)throw e;if(t>=10)throw console.error("Reached the maximum number of attempts!"),e;const n=t+Math.random();console.error(`Got error (attempts: ${t}, wait: ${n.toFixed(2)})`,e);const r=Math.ceil(n),o=n/r;for(let e=0;e<r;e++)console.warn(`Retrying in ${(n-e*o).toFixed(2)} seconds`),await j(1e3*o);t++}}function H(e){return[`background: ${e}`,"border: 1px solid rgba(0, 0, 0, 0.5)","border-radius: 2px","padding: 0 2px","color: #000","font-weight: bold"].join(";")}!function(e){e.MAYU_SESSION="application/vnd.mayu.session",e.MAYU_STREAM="application/vnd.mayu.eventstream"}(b||(b={}));var z=function(e="mayu/"){return{info:console.info.bind(console,`%c${e}info`,H("#35baf6")),log:console.info.bind(console,`%c${e}log`,H("#ccc")),error:console.error.bind(console,`%c${e}error`,H("#f6685e")),warn:console.warn.bind(console,`%c${e}warn`,H("#ffc107")),success:console.info.bind(console,`%c${e}success`,H("#a2cf6e")),group:console.group.bind(console),groupEnd:console.groupEnd.bind(console)}}();const V=new Promise((async e=>{if("undefined"!=typeof DecompressionStream)return z.success("Using standard DecompressionStream"),e(DecompressionStream);z.warn("Using DecompressionStream polyfill"),e((await import("./DecompressionStreamPolyfill-3ceba43e.js")).default)}));var K=await V;async function Y(e,t){const n=await function(e,t){if(!t)return F((()=>fetch(`/__mayu/session/${e}/init`,{method:"POST"})));return F((()=>fetch(`/__mayu/session/${e}/resume`,{method:"POST",headers:{"content-type":b.MAYU_SESSION},body:t})))}(e,t);if(!n.ok){const e=await n.text();if(503==n.status)throw new Error(`${n.status}: ${e}`);throw new R(`${n.status}: ${e}`)}if(!n.body)throw new R("body is null");const r=new K("deflate-raw");return n.body.pipeThrough(r)}function X(e){return e instanceof Error?e.message:"string"==typeof e?e:String(e)}async function*q(e){let t,n=!0,r=!1;const o=function(){const e=new m;return e.register({type:1,encode(){throw new Error("Not implemented")},decode:e=>new Blob([e],{type:"application/vnd.mayu.session"})}),e}();let i;for(;n;)try{const s=await F((()=>Y(e,t)));try{for await(const n of $(s,{extensionCodec:o})){const[o,s,a]=n;r||(r=!0,yield["system.connected",{}]),t&&(z.info("Clearing encryptedState"),t=void 0);try{switch(s){case"session.transfer":yield["session.transfer",{}],t=a,z.info("Setting encryptedState",a);break;case"pong":yield["ping",{values:{client:(new Date).getTime()-Number(a.pong),server:a.server},region:a.region,instance:a.instance}];break;case"ping":G(e,"ping",{pong:a,ping:(new Date).getTime()});break;default:yield[s,a]}}catch(e){i=X(e),z.error(e)}}}catch(e){i=X(e),z.error(e)}r=!1,n&&(i||="Stream ended unexpectedly"),yield["system.disconnected",{transferring:!!t,reason:i}]}catch(e){if(z.error(e),e instanceof R)return n=!1,r=!1,void(yield["system.disconnected",{reason:e.message}]);await j(1e3)}}async function G(e,t,n){return fetch(`/__mayu/session/${e}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:(r=n,JSON.stringify(r,((e,t)=>"bigint"==typeof t?Number(t):t instanceof Blob?`Blob{type: ${t.type}, size: ${t.size}}`:t),o))});var r,o}const J=function(){const e=(...e)=>{};return{info:e,log:e,warn:e,error:e,success:e,group:e,groupEnd:e}}();function Q(e,t){if("SCRIPT"!==t.tagName)for(const e of t.childNodes)Q(t,e);else e.replaceChild(function(e){const t=document.createElement("script");t.text=e.innerHTML;for(const n of e.attributes)t.setAttribute(n.name,n.value);return t}(t),t)}function W(e){if(e instanceof HTMLInputElement&&e.autofocus)e.focus();else for(const t of e.childNodes)W(t)}class Z{#e=new Map;constructor(e,t=document.documentElement){this.updateCache(t,e)}apply(e){for(const t of e)this.applyPatch(t)}applyPatch(e){switch(e.type){case"insert":return void this.insert(e);case"move":this.move(e);break;case"remove":this.remove(e.id);break;case"css":{const t=this.#t(e.id).node;e.value?t.style.setProperty(e.attr,e.value):t.style.removeProperty(e.attr)}case"text":"text"in e&&this.updateText(e.id,e.text),"append"in e&&this.appendText(e.id,e.append);break;case"attr":void 0!==e.value?this.setAttribute(e.id,e.name,e.value):this.removeAttribute(e.id,e.name);break;case"stylesheet":for(const t of e.paths){if(document.querySelector(`link[href="${t}"]`))continue;const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",t),document.head.insertAdjacentElement("beforeend",e)}break;default:console.error("Unknown patch",e)}}updateText(e,t){const n=this.#t(e).node;if(n.nodeType!==n.TEXT_NODE)throw new Error("Trying to update text on a non text node");n.textContent=t}appendText(e,t){const n=this.#t(e).node;if(n.nodeType!==n.TEXT_NODE)throw new Error("Trying to update text on a non text node");n.textContent+=t}setAttribute(e,t,n){const r=this.#t(e).node;"open"===t&&r instanceof HTMLDialogElement?r.showModal():r instanceof HTMLInputElement&&("value"===t&&(r.value=n),"checked"===t&&(r.checked=!0),"indeterminate"===t)?r.indeterminate=!0:(t="initial_value"===t?"value":t.replaceAll(/_/g,""),r.setAttribute(t,n))}removeAttribute(e,t){const n=this.#t(e).node;"open"===t&&n instanceof HTMLDialogElement&&(n.open=!1,n.close()),n instanceof HTMLInputElement&&("value"===t&&(n.value=""),"checked"===t&&(n.checked=!1),"indeterminate"===t)?n.indeterminate=!1:n.removeAttribute(t)}insert({parent:e,before:t,after:n,ids:r,html:o}){J.group("Trying to insert html into",e);const i=this.#t(e),s=t||n,a=s&&this.#e.get(s),c=document.createRange().createContextualFragment(`<template>${o}</template>`).firstElementChild.content,u=Array.from(c.childNodes).reverse();[r].flat().forEach(((e,t)=>{i.childIds.add(e.id);const r=this.#e.get(e.id),o=r?.node||u[t],s=a?n?a.node.nextSibling:a.node:null,c=i.node.insertBefore(o,s);r&&(r.node.outerHTML=o.outerHTML),requestIdleCallback((()=>{W(c)})),requestIdleCallback((()=>{Q(i.node,c)})),this.updateCache(c,e)})),J.groupEnd()}#t(e){const t=this.#e.get(e);if(!t)throw J.error("Could not find",e,"in cache!"),J.error(Array.from(this.#e.keys())),new Error(`Could not find ${e} in cache!`);return t}remove(e){J.info("Trying to remove",e);try{const t=this.#t(e),n=t.node.parentNode;if(n){const r=n.__MAYU_ID,o=this.#e.get(r);J.log("Removing child",t.node.textContent),n.removeChild(t.node),o&&o.childIds.delete(e)}else J.warn("Node",t.node.__MAYU_ID,"has no parent??");this.#n(e,!1)}catch(e){J.warn(e)}}move({id:e,parent:t,before:n,after:r}){const o=this.#t(e),i=this.#t(t),s=n||r,a=s&&this.#e.get(s),c=a?a.node:null;J.log("Moving",o.node.textContent,n?"before":r?"after":"last",c?.textContent||i.node.__MAYU_ID),J.log({before:n,after:r}),J.log(c?.textContent),i.node.insertBefore(o.node,c)}#n(e,t=!1){const n=this.#e.get(e);if(n){if(J.group("Removing from cache",e),t){this.#e.get(n.node.parentNode.__MAYU_ID)?.childIds?.delete(e)}this.#e.delete(e),n.childIds.forEach((e=>{this.#n(e,!1)})),n.childIds.delete(e),J.groupEnd()}}isIgnoredNode(e){if(e.nodeType===e.TEXT_NODE)return!1;if(e.nodeType===e.COMMENT_NODE)return!1;if(e.nodeType===e.ELEMENT_NODE){if("string"==typeof e.dataset.mayuId)return!1}return!0}updateCache(e,t){if(!e)throw J.error(t),new Error("No node found for idTreeNode");const n=new Set((t.ch||[]).map((e=>e.id)));this.#n(t.id),this.#e.set(t.id,{node:e,childIds:n}),e.__MAYU_ID=t.id,J.group("Add to cache",t.id,"type",e.nodeName,t.type);let r=0;const o=t.ch||[];e.childNodes.forEach((e=>{if(this.isIgnoredNode(e))return void J.warn("Ignored:",e);const n=o[r++];n?this.updateCache(e,n):J.error("No childIdNode at index",r,"on node",null,"with parent id",t.id,"and child node",null)})),o.length,J.groupEnd()}}function ee(e,t=[],n={}){const r=document.createElement(e);for(const[e,t]of Object.entries(n))t&&(!0===t?r.setAttribute(e,e):r.setAttribute(e,t));return t.forEach((e=>{e instanceof Node?r.appendChild(e):e&&r.appendChild(document.createTextNode(String(e)))})),r}function te(e){if(e instanceof HTMLFormElement){const t=Object.fromEntries(new FormData(e).entries());return{tagName:e.tagName,id:e.id,method:e.method,target:e.target,name:e.name,formData:t}}return e instanceof HTMLSelectElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value}:e instanceof HTMLDetailsElement?{tagName:e.tagName,id:e.id,open:e.open}:e instanceof HTMLInputElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value,checked:e.checked}:e instanceof HTMLButtonElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value}:e instanceof HTMLElement?{tagName:e.tagName,id:e.id}:{}}const ne=new Promise((e=>{if("loading"!==document.readyState)return e();window.addEventListener("DOMContentLoaded",(()=>e()))}));async function re({type:e,message:t,backtrace:n}){await import("./custom-elements/mayu-exception-63df4e8c.js");const r=n.filter((e=>!/\/vendor\/bundle\//.test(e))).join("\n"),o=ee("mayu-exception",[ee("span",[`${e}: ${t}`],{slot:"title"}),ee("span",[r],{slot:"backtrace"})]);document.body.appendChild(o)}class oe{#r;constructor(e){this.#r=e,ne.then((()=>{window.addEventListener("popstate",(()=>ie(this.#r,location.pathname)))}))}async handle(e,t){(function(e){return!("undefined"!=typeof TouchEvent&&e instanceof TouchEvent)})(e)&&e.preventDefault();const n=function(e){const t={};return t.type=e.constructor.name,e.currentTarget&&(t.currentTarget=te(e.currentTarget)),e.target&&(t.target=te(e.target)),e instanceof MouseEvent&&(t.buttons=e.buttons),e instanceof SubmitEvent&&e.submitter instanceof HTMLElement&&(t.submitter=te(e.submitter)),t}(e);console.log(n),await function(e,t,n){return fetch(`/__mayu/session/${e}/callback/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}(this.#r,t,n);const r=setTimeout((()=>{}),1);clearTimeout(r)}async navigate(e){if(e.metaKey||e.ctrlKey)return;e.preventDefault();const t=e.target.closest("a");if(!t)return void z.error("Could not find anchor element for",e.target);const n=new URL(t.href);return ie(this.#r,n.pathname+n.search)}}async function ie(e,t){return fetch(`/__mayu/session/${e}/navigate`,{method:"POST",headers:{"content-type":"text/plain; charset=utf-8"},body:t})}var se=async function(e){const t=function(e){const t=e.lastIndexOf("#");if(-1===t)throw new Error(`No # found in script url: ${e}`);return e.slice(t+1)}(e),n=new oe(t);let r;window.Mayu=n;const o=document.createElement("mayu-disconnected"),i=document.createElement("mayu-ping");i.setAttribute("region","Connecting..."),i.setAttribute("status","connecting"),document.body.appendChild(i);for await(const[e,n]of q(t))switch(e){case"system.connected":import("./custom-elements/mayu-ping-c498c2a6.js"),import("./custom-elements/mayu-disconnected-9f349f46.js"),import("./custom-elements/mayu-progress-bar-eb3e1ac8.js"),import("./custom-elements/mayu-exception-63df4e8c.js"),import("./custom-elements/mayu-alert-cd7ad2a4.js"),i.setAttribute("region","Connected!"),i.setAttribute("status","connected"),z.success("Connected!"),document.body.querySelectorAll("mayu-disconnected").forEach((e=>e.remove()));break;case"system.disconnected":if(n.transferring){i.setAttribute("region","Transferring…"),i.setAttribute("status","transferring");break}i.setAttribute("region","Disconnected"),i.setAttribute("status","disconnected"),z.error("Disconnected"),o.setAttribute("reason",n.reason),o.parentElement!==document.body&&document.body.appendChild(o);break;case"session.init":await ne,r=new Z(n.ids);break;case"session.patch":r?.apply(n);break;case"session.navigate":const t=n.path;t!==location.pathname&&(z.info("Navigating to",t),history.pushState({},"",t));break;case"session.action":s(n.type,n.payload);break;case"session.keep_alive":break;case"session.transfer":i.setAttribute("region","Transferring"),i.setAttribute("status","transferring");break;case"session.exception":re(n);break;case"ping":const a=Object.values(n.values),c=a.reduce(((e,t)=>e+t),0)/a.length;i.setAttribute("ping",`${c.toFixed(2)} ms`),i.setAttribute("region",`${n.instance} @ ${n.region}`),i.setAttribute("status","ping");break;default:z.warn("Unhandled event:",e,n)}function s(e,t){switch(e){case"scroll_into_view":!function(e,t){const n=document.querySelector(e);n?n.scrollIntoView({block:"start",inline:"nearest",behavior:"smooth",...t}):console.error("Could not find element to scrollIntoView, selector:",e)}(t.selector,t.options||{});break;case"alert":!async function(e){await import("./custom-elements/mayu-alert-cd7ad2a4.js");const t=document.createElement("mayu-alert");t.setAttribute("message",e),document.body.appendChild(t)}(t);break;default:z.error("Unhandled action:",e,t)}}}(import.meta.url);export{se as default};//# sourceMappingURL=main-4b49dbc4.js.map
1
+ var e,t,n,r=4294967295;function o(e,t){return 4294967296*e.getInt32(t)+e.getUint32(t+4)}var i=("undefined"==typeof process||"never"!==(null===(e=null===process||void 0===process?void 0:process.env)||void 0===e?void 0:e.TEXT_ENCODING))&&"undefined"!=typeof TextEncoder&&"undefined"!=typeof TextDecoder,s=i?new TextEncoder:void 0;i&&"undefined"!=typeof process&&(null===(t=null===process||void 0===process?void 0:process.env)||void 0===t||t.TEXT_ENCODING),null==s||s.encodeInto;function a(e,t,n){for(var r=t,o=r+n,i=[],s="";r<o;){var a=e[r++];if(0==(128&a))i.push(a);else if(192==(224&a)){var c=63&e[r++];i.push((31&a)<<6|c)}else if(224==(240&a)){c=63&e[r++];var u=63&e[r++];i.push((31&a)<<12|c<<6|u)}else if(240==(248&a)){var h=(7&a)<<18|(c=63&e[r++])<<12|(u=63&e[r++])<<6|63&e[r++];h>65535&&(h-=65536,i.push(h>>>10&1023|55296),h=56320|1023&h),i.push(h)}else i.push(a);i.length>=4096&&(s+=String.fromCharCode.apply(String,i),i.length=0)}return i.length>0&&(s+=String.fromCharCode.apply(String,i)),s}var c=i?new TextDecoder:null,u=i?"undefined"!=typeof process&&"force"!==(null===(n=null===process||void 0===process?void 0:process.env)||void 0===n?void 0:n.TEXT_DECODER)?200:0:r;var h,d=function(e,t){this.type=e,this.data=t},l=(h=function(e,t){return h=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},h(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}h(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),f=function(e){function t(n){var r=e.call(this,n)||this,o=Object.create(t.prototype);return Object.setPrototypeOf(r,o),Object.defineProperty(r,"name",{configurable:!0,enumerable:!1,value:t.name}),r}return l(t,e),t}(Error);function p(e){var t=e.sec,n=e.nsec;if(t>=0&&n>=0&&t<=17179869183){if(0===n&&t<=4294967295){var r=new Uint8Array(4);return(s=new DataView(r.buffer)).setUint32(0,t),r}var o=t/4294967296,i=4294967295&t;r=new Uint8Array(8);return(s=new DataView(r.buffer)).setUint32(0,n<<2|3&o),s.setUint32(4,i),r}var s;r=new Uint8Array(12);return(s=new DataView(r.buffer)).setUint32(0,n),function(e,t,n){var r=Math.floor(n/4294967296),o=n;e.setUint32(t,r),e.setUint32(t+4,o)}(s,4,t),r}var y={type:-1,encode:function(e){var t,n,r,o;return e instanceof Date?p((t=e.getTime(),n=Math.floor(t/1e3),r=1e6*(t-1e3*n),o=Math.floor(r/1e9),{sec:n+o,nsec:r-1e9*o})):null},decode:function(e){var t=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:t.getUint32(0),nsec:0};case 8:var n=t.getUint32(0);return{sec:4294967296*(3&n)+t.getUint32(4),nsec:n>>>2};case 12:return{sec:o(t,4),nsec:t.getUint32(0)};default:throw new f("Unrecognized data size for timestamp (expected 4, 8, or 12): ".concat(e.length))}}(e);return new Date(1e3*t.sec+t.nsec/1e6)}},m=function(){function e(){this.builtInEncoders=[],this.builtInDecoders=[],this.encoders=[],this.decoders=[],this.register(y)}return e.prototype.register=function(e){var t=e.type,n=e.encode,r=e.decode;if(t>=0)this.encoders[t]=n,this.decoders[t]=r;else{var o=1+t;this.builtInEncoders[o]=n,this.builtInDecoders[o]=r}},e.prototype.tryToEncode=function(e,t){for(var n=0;n<this.builtInEncoders.length;n++){if(null!=(r=this.builtInEncoders[n]))if(null!=(o=r(e,t)))return new d(-1-n,o)}for(n=0;n<this.encoders.length;n++){var r,o;if(null!=(r=this.encoders[n]))if(null!=(o=r(e,t)))return new d(n,o)}return e instanceof d?e:null},e.prototype.decode=function(e,t,n){var r=t<0?this.builtInDecoders[-1-t]:this.decoders[t];return r?r(e,t,n):new d(t,e)},e.defaultCodec=new e,e}();function g(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?new Uint8Array(e):Uint8Array.from(e)}function v(e){return"".concat(e<0?"-":"","0x").concat(Math.abs(e).toString(16).padStart(2,"0"))}var b,w=function(){function e(e,t){void 0===e&&(e=16),void 0===t&&(t=16),this.maxKeyLength=e,this.maxLengthPerKey=t,this.hit=0,this.miss=0,this.caches=[];for(var n=0;n<this.maxKeyLength;n++)this.caches.push([])}return e.prototype.canBeCached=function(e){return e>0&&e<=this.maxKeyLength},e.prototype.find=function(e,t,n){e:for(var r=0,o=this.caches[n-1];r<o.length;r++){for(var i=o[r],s=i.bytes,a=0;a<n;a++)if(s[a]!==e[t+a])continue e;return i.str}return null},e.prototype.store=function(e,t){var n=this.caches[e.length-1],r={bytes:e,str:t};n.length>=this.maxLengthPerKey?n[Math.random()*n.length|0]=r:n.push(r)},e.prototype.decode=function(e,t,n){var r=this.find(e,t,n);if(null!=r)return this.hit++,r;this.miss++;var o=a(e,t,n),i=Uint8Array.prototype.slice.call(e,t,t+n);return this.store(i,o),o},e}(),x=function(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function a(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))},E=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){s.label=i[1];break}if(6===i[0]&&s.label<o[1]){s.label=o[1],o=i;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(i);break}o[2]&&s.ops.pop(),s.trys.pop();continue}i=t.call(e,s)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},S=function(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e="function"==typeof __values?__values(e):e[Symbol.iterator](),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}},U=function(e){return this instanceof U?(this.v=e,this):new U(e)},k=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r={},s("next"),s("throw"),s("return"),r[Symbol.asyncIterator]=function(){return this},r;function s(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){i.push([e,t,n,r])>1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof U?Promise.resolve(n.value.v).then(c,u):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function u(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}},T=new DataView(new ArrayBuffer(0)),A=new Uint8Array(T.buffer),I=function(){try{T.getInt8(0)}catch(e){return e.constructor}throw new Error("never reached")}(),_=new I("Insufficient data"),L=new w,M=function(){function e(e,t,n,o,i,s,a,c){void 0===e&&(e=m.defaultCodec),void 0===t&&(t=void 0),void 0===n&&(n=r),void 0===o&&(o=r),void 0===i&&(i=r),void 0===s&&(s=r),void 0===a&&(a=r),void 0===c&&(c=L),this.extensionCodec=e,this.context=t,this.maxStrLength=n,this.maxBinLength=o,this.maxArrayLength=i,this.maxMapLength=s,this.maxExtLength=a,this.keyDecoder=c,this.totalPos=0,this.pos=0,this.view=T,this.bytes=A,this.headByte=-1,this.stack=[]}return e.prototype.reinitializeState=function(){this.totalPos=0,this.headByte=-1,this.stack.length=0},e.prototype.setBuffer=function(e){this.bytes=g(e),this.view=function(e){if(e instanceof ArrayBuffer)return new DataView(e);var t=g(e);return new DataView(t.buffer,t.byteOffset,t.byteLength)}(this.bytes),this.pos=0},e.prototype.appendBuffer=function(e){if(-1!==this.headByte||this.hasRemaining(1)){var t=this.bytes.subarray(this.pos),n=g(e),r=new Uint8Array(t.length+n.length);r.set(t),r.set(n,t.length),this.setBuffer(r)}else this.setBuffer(e)},e.prototype.hasRemaining=function(e){return this.view.byteLength-this.pos>=e},e.prototype.createExtraByteError=function(e){var t=this.view,n=this.pos;return new RangeError("Extra ".concat(t.byteLength-n," of ").concat(t.byteLength," byte(s) found at buffer[").concat(e,"]"))},e.prototype.decode=function(e){this.reinitializeState(),this.setBuffer(e);var t=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return t},e.prototype.decodeMulti=function(e){return E(this,(function(t){switch(t.label){case 0:this.reinitializeState(),this.setBuffer(e),t.label=1;case 1:return this.hasRemaining(1)?[4,this.doDecodeSync()]:[3,3];case 2:return t.sent(),[3,1];case 3:return[2]}}))},e.prototype.decodeAsync=function(e){var t,n,r,o;return x(this,void 0,void 0,(function(){var i,s,a,c,u,h,d,l;return E(this,(function(f){switch(f.label){case 0:i=!1,f.label=1;case 1:f.trys.push([1,6,7,12]),t=S(e),f.label=2;case 2:return[4,t.next()];case 3:if((n=f.sent()).done)return[3,5];if(a=n.value,i)throw this.createExtraByteError(this.totalPos);this.appendBuffer(a);try{s=this.doDecodeSync(),i=!0}catch(e){if(!(e instanceof I))throw e}this.totalPos+=this.pos,f.label=4;case 4:return[3,2];case 5:return[3,12];case 6:return c=f.sent(),r={error:c},[3,12];case 7:return f.trys.push([7,,10,11]),n&&!n.done&&(o=t.return)?[4,o.call(t)]:[3,9];case 8:f.sent(),f.label=9;case 9:return[3,11];case 10:if(r)throw r.error;return[7];case 11:return[7];case 12:if(i){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return[2,s]}throw h=(u=this).headByte,d=u.pos,l=u.totalPos,new RangeError("Insufficient data in parsing ".concat(v(h)," at ").concat(l," (").concat(d," in the current buffer)"))}}))}))},e.prototype.decodeArrayStream=function(e){return this.decodeMultiAsync(e,!0)},e.prototype.decodeStream=function(e){return this.decodeMultiAsync(e,!1)},e.prototype.decodeMultiAsync=function(e,t){return k(this,arguments,(function(){var n,r,o,i,s,a,c,u,h;return E(this,(function(d){switch(d.label){case 0:n=t,r=-1,d.label=1;case 1:d.trys.push([1,13,14,19]),o=S(e),d.label=2;case 2:return[4,U(o.next())];case 3:if((i=d.sent()).done)return[3,12];if(s=i.value,t&&0===r)throw this.createExtraByteError(this.totalPos);this.appendBuffer(s),n&&(r=this.readArraySize(),n=!1,this.complete()),d.label=4;case 4:d.trys.push([4,9,,10]),d.label=5;case 5:return[4,U(this.doDecodeSync())];case 6:return[4,d.sent()];case 7:return d.sent(),0==--r?[3,8]:[3,5];case 8:return[3,10];case 9:if(!((a=d.sent())instanceof I))throw a;return[3,10];case 10:this.totalPos+=this.pos,d.label=11;case 11:return[3,2];case 12:return[3,19];case 13:return c=d.sent(),u={error:c},[3,19];case 14:return d.trys.push([14,,17,18]),i&&!i.done&&(h=o.return)?[4,U(h.call(o))]:[3,16];case 15:d.sent(),d.label=16;case 16:return[3,18];case 17:if(u)throw u.error;return[7];case 18:return[7];case 19:return[2]}}))}))},e.prototype.doDecodeSync=function(){e:for(;;){var e=this.readHeadByte(),t=void 0;if(e>=224)t=e-256;else if(e<192)if(e<128)t=e;else if(e<144){if(0!==(r=e-128)){this.pushMapState(r),this.complete();continue e}t={}}else if(e<160){if(0!==(r=e-144)){this.pushArrayState(r),this.complete();continue e}t=[]}else{var n=e-160;t=this.decodeUtf8String(n,0)}else if(192===e)t=null;else if(194===e)t=!1;else if(195===e)t=!0;else if(202===e)t=this.readF32();else if(203===e)t=this.readF64();else if(204===e)t=this.readU8();else if(205===e)t=this.readU16();else if(206===e)t=this.readU32();else if(207===e)t=this.readU64();else if(208===e)t=this.readI8();else if(209===e)t=this.readI16();else if(210===e)t=this.readI32();else if(211===e)t=this.readI64();else if(217===e){n=this.lookU8();t=this.decodeUtf8String(n,1)}else if(218===e){n=this.lookU16();t=this.decodeUtf8String(n,2)}else if(219===e){n=this.lookU32();t=this.decodeUtf8String(n,4)}else if(220===e){if(0!==(r=this.readU16())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(221===e){if(0!==(r=this.readU32())){this.pushArrayState(r),this.complete();continue e}t=[]}else if(222===e){if(0!==(r=this.readU16())){this.pushMapState(r),this.complete();continue e}t={}}else if(223===e){if(0!==(r=this.readU32())){this.pushMapState(r),this.complete();continue e}t={}}else if(196===e){var r=this.lookU8();t=this.decodeBinary(r,1)}else if(197===e){r=this.lookU16();t=this.decodeBinary(r,2)}else if(198===e){r=this.lookU32();t=this.decodeBinary(r,4)}else if(212===e)t=this.decodeExtension(1,0);else if(213===e)t=this.decodeExtension(2,0);else if(214===e)t=this.decodeExtension(4,0);else if(215===e)t=this.decodeExtension(8,0);else if(216===e)t=this.decodeExtension(16,0);else if(199===e){r=this.lookU8();t=this.decodeExtension(r,1)}else if(200===e){r=this.lookU16();t=this.decodeExtension(r,2)}else{if(201!==e)throw new f("Unrecognized type byte: ".concat(v(e)));r=this.lookU32();t=this.decodeExtension(r,4)}this.complete();for(var o=this.stack;o.length>0;){var i=o[o.length-1];if(0===i.type){if(i.array[i.position]=t,i.position++,i.position!==i.size)continue e;o.pop(),t=i.array}else{if(1===i.type){if(s=void 0,"string"!==(s=typeof t)&&"number"!==s)throw new f("The type of key must be string or number but "+typeof t);if("__proto__"===t)throw new f("The key __proto__ is not allowed");i.key=t,i.type=2;continue e}if(i.map[i.key]=t,i.readCount++,i.readCount!==i.size){i.key=null,i.type=1;continue e}o.pop(),t=i.map}}return t}var s},e.prototype.readHeadByte=function(){return-1===this.headByte&&(this.headByte=this.readU8()),this.headByte},e.prototype.complete=function(){this.headByte=-1},e.prototype.readArraySize=function(){var e=this.readHeadByte();switch(e){case 220:return this.readU16();case 221:return this.readU32();default:if(e<160)return e-144;throw new f("Unrecognized array type byte: ".concat(v(e)))}},e.prototype.pushMapState=function(e){if(e>this.maxMapLength)throw new f("Max length exceeded: map length (".concat(e,") > maxMapLengthLength (").concat(this.maxMapLength,")"));this.stack.push({type:1,size:e,key:null,readCount:0,map:{}})},e.prototype.pushArrayState=function(e){if(e>this.maxArrayLength)throw new f("Max length exceeded: array length (".concat(e,") > maxArrayLength (").concat(this.maxArrayLength,")"));this.stack.push({type:0,size:e,array:new Array(e),position:0})},e.prototype.decodeUtf8String=function(e,t){var n;if(e>this.maxStrLength)throw new f("Max length exceeded: UTF-8 byte length (".concat(e,") > maxStrLength (").concat(this.maxStrLength,")"));if(this.bytes.byteLength<this.pos+t+e)throw _;var r,o=this.pos+t;return r=this.stateIsMapKey()&&(null===(n=this.keyDecoder)||void 0===n?void 0:n.canBeCached(e))?this.keyDecoder.decode(this.bytes,o,e):e>u?function(e,t,n){var r=e.subarray(t,t+n);return c.decode(r)}(this.bytes,o,e):a(this.bytes,o,e),this.pos+=t+e,r},e.prototype.stateIsMapKey=function(){return this.stack.length>0&&1===this.stack[this.stack.length-1].type},e.prototype.decodeBinary=function(e,t){if(e>this.maxBinLength)throw new f("Max length exceeded: bin length (".concat(e,") > maxBinLength (").concat(this.maxBinLength,")"));if(!this.hasRemaining(e+t))throw _;var n=this.pos+t,r=this.bytes.subarray(n,n+e);return this.pos+=t+e,r},e.prototype.decodeExtension=function(e,t){if(e>this.maxExtLength)throw new f("Max length exceeded: ext length (".concat(e,") > maxExtLength (").concat(this.maxExtLength,")"));var n=this.view.getInt8(this.pos+t),r=this.decodeBinary(e,t+1);return this.extensionCodec.decode(r,n,this.context)},e.prototype.lookU8=function(){return this.view.getUint8(this.pos)},e.prototype.lookU16=function(){return this.view.getUint16(this.pos)},e.prototype.lookU32=function(){return this.view.getUint32(this.pos)},e.prototype.readU8=function(){var e=this.view.getUint8(this.pos);return this.pos++,e},e.prototype.readI8=function(){var e=this.view.getInt8(this.pos);return this.pos++,e},e.prototype.readU16=function(){var e=this.view.getUint16(this.pos);return this.pos+=2,e},e.prototype.readI16=function(){var e=this.view.getInt16(this.pos);return this.pos+=2,e},e.prototype.readU32=function(){var e=this.view.getUint32(this.pos);return this.pos+=4,e},e.prototype.readI32=function(){var e=this.view.getInt32(this.pos);return this.pos+=4,e},e.prototype.readU64=function(){var e,t,n=(e=this.view,t=this.pos,4294967296*e.getUint32(t)+e.getUint32(t+4));return this.pos+=8,n},e.prototype.readI64=function(){var e=o(this.view,this.pos);return this.pos+=8,e},e.prototype.readF32=function(){var e=this.view.getFloat32(this.pos);return this.pos+=4,e},e.prototype.readF64=function(){var e=this.view.getFloat64(this.pos);return this.pos+=8,e},e}(),C={},D=function(e,t){var n,r,o,i,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,r=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!(o=s.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){s.label=i[1];break}if(6===i[0]&&s.label<o[1]){s.label=o[1],o=i;break}if(o&&s.label<o[2]){s.label=o[2],s.ops.push(i);break}o[2]&&s.ops.pop(),s.trys.pop();continue}i=t.call(e,s)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},N=function(e){return this instanceof N?(this.v=e,this):new N(e)},B=function(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),i=[];return r={},s("next"),s("throw"),s("return"),r[Symbol.asyncIterator]=function(){return this},r;function s(e){o[e]&&(r[e]=function(t){return new Promise((function(n,r){i.push([e,t,n,r])>1||a(e,t)}))})}function a(e,t){try{(n=o[e](t)).value instanceof N?Promise.resolve(n.value.v).then(c,u):h(i[0][2],n)}catch(e){h(i[0][3],e)}var n}function c(e){a("next",e)}function u(e){a("throw",e)}function h(e,t){e(t),i.shift(),i.length&&a(i[0][0],i[0][1])}};function P(e){if(null==e)throw new Error("Assertion Failure: value must not be null nor undefined")}function O(e){return null!=e[Symbol.asyncIterator]?e:function(e){return B(this,arguments,(function(){var t,n,r,o;return D(this,(function(i){switch(i.label){case 0:t=e.getReader(),i.label=1;case 1:i.trys.push([1,,9,10]),i.label=2;case 2:return[4,N(t.read())];case 3:return n=i.sent(),r=n.done,o=n.value,r?[4,N(void 0)]:[3,5];case 4:return[2,i.sent()];case 5:return P(o),[4,N(o)];case 6:return[4,i.sent()];case 7:return i.sent(),[3,2];case 8:return[3,10];case 9:return t.releaseLock(),[7];case 10:return[2]}}))}))}(e)}function $(e,t){void 0===t&&(t=C);var n=O(e);return new M(t.extensionCodec,t.context,t.maxStrLength,t.maxBinLength,t.maxArrayLength,t.maxMapLength,t.maxExtLength).decodeStream(n)}async function j(e=1e3){return new Promise((t=>{setTimeout(t,e)}))}class R extends Error{}async function F(e){let t=0;for(;;)try{return await e()}catch(e){if(e instanceof R)throw e;if(t>=10)throw console.error("Reached the maximum number of attempts!"),e;const n=t+Math.random();console.error(`Got error (attempts: ${t}, wait: ${n.toFixed(2)})`,e);const r=Math.ceil(n),o=n/r;for(let e=0;e<r;e++)console.warn(`Retrying in ${(n-e*o).toFixed(2)} seconds`),await j(1e3*o);t++}}function H(e){return[`background: ${e}`,"border: 1px solid rgba(0, 0, 0, 0.5)","border-radius: 2px","padding: 0 2px","color: #000","font-weight: bold"].join(";")}!function(e){e.MAYU_SESSION="application/vnd.mayu.session",e.MAYU_STREAM="application/vnd.mayu.eventstream"}(b||(b={}));var z=function(e="mayu/"){return{info:console.info.bind(console,`%c${e}info`,H("#35baf6")),log:console.info.bind(console,`%c${e}log`,H("#ccc")),error:console.error.bind(console,`%c${e}error`,H("#f6685e")),warn:console.warn.bind(console,`%c${e}warn`,H("#ffc107")),success:console.info.bind(console,`%c${e}success`,H("#a2cf6e")),group:console.group.bind(console),groupEnd:console.groupEnd.bind(console)}}();const V=new Promise((async e=>{if("undefined"!=typeof DecompressionStream)return z.success("Using standard DecompressionStream"),e(DecompressionStream);z.warn("Using DecompressionStream polyfill"),e((await import("./DecompressionStreamPolyfill-3ceba43e.js")).default)}));var K=await V;async function q(e,t){const n=await function(e,t){if(!t)return F((()=>fetch(`/__mayu/session/${e}/init`,{method:"POST"})));return F((()=>fetch(`/__mayu/session/${e}/resume`,{method:"POST",headers:{"content-type":b.MAYU_SESSION},body:t})))}(e,t);if(!n.ok){const e=await n.text();if(503==n.status)throw new Error(`${n.status}: ${e}`);throw new R(`${n.status}: ${e}`)}if(!n.body)throw new R("body is null");const r=new K("deflate-raw");return n.body.pipeThrough(r)}function Y(e){return e instanceof Error?e.message:"string"==typeof e?e:String(e)}async function*X(e){let t,n=!0,r=!1;const o=function(){const e=new m;return e.register({type:1,encode(){throw new Error("Not implemented")},decode:e=>new Blob([e],{type:"application/vnd.mayu.session"})}),e}();let i;for(;n;)try{const s=await F((()=>q(e,t)));try{for await(const n of $(s,{extensionCodec:o})){const[o,s,a]=n;r||(r=!0,yield["system.connected",{}]),t&&(z.info("Clearing encryptedState"),t=void 0);try{switch(s){case"session.transfer":yield["session.transfer",{}],t=a,z.info("Setting encryptedState",a);break;case"pong":yield["ping",{values:{client:performance.now()-Number(a.pong),server:a.server},region:a.region,instance:a.instance}];break;case"ping":G(e,"ping",{pong:a,ping:performance.now()});break;default:yield[s,a]}}catch(e){i=Y(e),z.error(e)}}}catch(e){i=Y(e),z.error(e)}r=!1,n&&(i||="Stream ended unexpectedly"),yield["system.disconnected",{transferring:!!t,reason:i}]}catch(e){if(z.error(e),e instanceof R)return n=!1,r=!1,void(yield["system.disconnected",{reason:e.message}]);await j(1e3)}}async function G(e,t,n){return fetch(`/__mayu/session/${e}/${t}`,{method:"POST",headers:{"content-type":"application/json"},body:(r=n,JSON.stringify(r,((e,t)=>"bigint"==typeof t?Number(t):t instanceof Blob?`Blob{type: ${t.type}, size: ${t.size}}`:t),o))});var r,o}const J=function(){const e=(...e)=>{};return{info:e,log:e,warn:e,error:e,success:e,group:e,groupEnd:e}}();function Q(e,t){if("SCRIPT"!==t.tagName)for(const e of t.childNodes)Q(t,e);else e.replaceChild(function(e){const t=document.createElement("script");t.text=e.innerHTML;for(const n of e.attributes)t.setAttribute(n.name,n.value);return t}(t),t)}function W(e){if(e instanceof HTMLInputElement&&e.autofocus)e.focus();else for(const t of e.childNodes)W(t)}class Z{#e=new Map;constructor(e,t=document.documentElement){this.updateCache(t,e)}apply(e){for(const t of e)this.applyPatch(t)}applyPatch(e){switch(e.type){case"insert":return void this.insert(e);case"move":this.move(e);break;case"remove":this.remove(e.id);break;case"css":{const t=this.#t(e.id).node;e.value?t.style.setProperty(e.attr,e.value):t.style.removeProperty(e.attr)}case"text":"text"in e&&this.updateText(e.id,e.text),"append"in e&&this.appendText(e.id,e.append);break;case"attr":void 0!==e.value?this.setAttribute(e.id,e.name,e.value):this.removeAttribute(e.id,e.name);break;case"stylesheet":for(const t of e.paths){if(document.querySelector(`link[href="${t}"]`))continue;const e=document.createElement("link");e.setAttribute("rel","stylesheet"),e.setAttribute("href",t),document.head.insertAdjacentElement("beforeend",e)}break;default:console.error("Unknown patch",e)}}updateText(e,t){const n=this.#t(e).node;if(n.nodeType!==n.TEXT_NODE)throw new Error("Trying to update text on a non text node");n.textContent=t}appendText(e,t){const n=this.#t(e).node;if(n.nodeType!==n.TEXT_NODE)throw new Error("Trying to update text on a non text node");n.textContent+=t}setAttribute(e,t,n){const r=this.#t(e).node;"open"===t&&r instanceof HTMLDialogElement?r.showModal():r instanceof HTMLInputElement&&("value"===t&&(r.value=n),"checked"===t&&(r.checked=!0),"indeterminate"===t)?r.indeterminate=!0:(t="initial_value"===t?"value":t.replaceAll(/_/g,""),r.setAttribute(t,n))}removeAttribute(e,t){const n=this.#t(e).node;"open"===t&&n instanceof HTMLDialogElement&&(n.open=!1,n.close()),n instanceof HTMLInputElement&&("value"===t&&(n.value=""),"checked"===t&&(n.checked=!1),"indeterminate"===t)?n.indeterminate=!1:n.removeAttribute(t)}insert({parent:e,before:t,after:n,ids:r,html:o}){J.group("Trying to insert html into",e);const i=this.#t(e),s=t||n,a=s&&this.#e.get(s),c=document.createRange().createContextualFragment(`<template>${o}</template>`).firstElementChild.content,u=Array.from(c.childNodes).reverse();[r].flat().forEach(((e,t)=>{i.childIds.add(e.id);const r=this.#e.get(e.id),o=r?.node||u[t],s=a?n?a.node.nextSibling:a.node:null,c=i.node.insertBefore(o,s);r&&(r.node.outerHTML=o.outerHTML),requestIdleCallback((()=>{W(c)})),requestIdleCallback((()=>{Q(i.node,c)})),this.updateCache(c,e)})),J.groupEnd()}#t(e){const t=this.#e.get(e);if(!t)throw J.error("Could not find",e,"in cache!"),J.error(Array.from(this.#e.keys())),new Error(`Could not find ${e} in cache!`);return t}remove(e){J.info("Trying to remove",e);try{const t=this.#t(e),n=t.node.parentNode;if(n){const r=n.__MAYU_ID,o=this.#e.get(r);J.log("Removing child",t.node.textContent),n.removeChild(t.node),o&&o.childIds.delete(e)}else J.warn("Node",t.node.__MAYU_ID,"has no parent??");this.#n(e,!1)}catch(e){J.warn(e)}}move({id:e,parent:t,before:n,after:r}){const o=this.#t(e),i=this.#t(t),s=n||r,a=s&&this.#e.get(s),c=a?a.node:null;J.log("Moving",o.node.textContent,n?"before":r?"after":"last",c?.textContent||i.node.__MAYU_ID),J.log({before:n,after:r}),J.log(c?.textContent),i.node.insertBefore(o.node,c)}#n(e,t=!1){const n=this.#e.get(e);if(n){if(J.group("Removing from cache",e),t){this.#e.get(n.node.parentNode.__MAYU_ID)?.childIds?.delete(e)}this.#e.delete(e),n.childIds.forEach((e=>{this.#n(e,!1)})),n.childIds.delete(e),J.groupEnd()}}isIgnoredNode(e){if(e.nodeType===e.TEXT_NODE)return!1;if(e.nodeType===e.COMMENT_NODE)return!1;if(e.nodeType===e.ELEMENT_NODE){if("string"==typeof e.dataset.mayuId)return!1}return!0}updateCache(e,t){if(!e)throw J.error(t),new Error("No node found for idTreeNode");const n=new Set((t.ch||[]).map((e=>e.id)));this.#n(t.id),this.#e.set(t.id,{node:e,childIds:n}),e.__MAYU_ID=t.id,J.group("Add to cache",t.id,"type",e.nodeName,t.type);let r=0;const o=t.ch||[];e.childNodes.forEach((e=>{if(this.isIgnoredNode(e))return void J.warn("Ignored:",e);const n=o[r++];n?this.updateCache(e,n):J.error("No childIdNode at index",r,"on node",null,"with parent id",t.id,"and child node",null)})),o.length,J.groupEnd()}}function ee(e,t=[],n={}){const r=document.createElement(e);for(const[e,t]of Object.entries(n))t&&(!0===t?r.setAttribute(e,e):r.setAttribute(e,t));return t.forEach((e=>{e instanceof Node?r.appendChild(e):e&&r.appendChild(document.createTextNode(String(e)))})),r}function te(e){if(e instanceof HTMLFormElement){const t=Object.fromEntries(new FormData(e).entries());return{tagName:e.tagName,id:e.id,method:e.method,target:e.target,name:e.name,formData:t}}return e instanceof HTMLSelectElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value}:e instanceof HTMLDetailsElement?{tagName:e.tagName,id:e.id,open:e.open}:e instanceof HTMLInputElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value,checked:e.checked}:e instanceof HTMLButtonElement?{tagName:e.tagName,id:e.id,type:e.type,name:e.name,value:e.value}:e instanceof HTMLElement?{tagName:e.tagName,id:e.id}:{}}const ne=new Promise((e=>{if("loading"!==document.readyState)return e();window.addEventListener("DOMContentLoaded",(()=>e()))}));async function re({type:e,message:t,backtrace:n}){await import("./custom-elements/mayu-exception-63df4e8c.js");const r=n.filter((e=>!/\/vendor\/bundle\//.test(e))).join("\n"),o=ee("mayu-exception",[ee("span",[`${e}: ${t}`],{slot:"title"}),ee("span",[r],{slot:"backtrace"})]);document.body.appendChild(o)}class oe{#r;constructor(e){this.#r=e,ne.then((()=>{window.addEventListener("popstate",(()=>ie(this.#r,location.pathname)))}))}async handle(e,t){(function(e){return!("undefined"!=typeof TouchEvent&&e instanceof TouchEvent)})(e)&&e.preventDefault();const n=function(e){const t={};return t.type=e.constructor.name,e.currentTarget&&(t.currentTarget=te(e.currentTarget)),e.target&&(t.target=te(e.target)),e instanceof MouseEvent&&(t.buttons=e.buttons),e instanceof SubmitEvent&&e.submitter instanceof HTMLElement&&(t.submitter=te(e.submitter)),t}(e);console.log(n),await function(e,t,n){return fetch(`/__mayu/session/${e}/callback/${t}`,{method:"POST",headers:{"content-type":"application/json","x-request-time":performance.now()},body:JSON.stringify(n)}).then(se)}(this.#r,t,n);const r=setTimeout((()=>{}),1);clearTimeout(r)}async navigate(e){if(e.metaKey||e.ctrlKey)return;e.preventDefault();const t=e.target.closest("a");if(!t)return void z.error("Could not find anchor element for",e.target);const n=new URL(t.href);return ie(this.#r,n.pathname+n.search)}}async function ie(e,t){return fetch(`/__mayu/session/${e}/navigate`,{method:"POST",headers:{"content-type":"text/plain; charset=utf-8","x-request-time":performance.now()},body:t}).then(se)}function se(e){const t=e.headers.get("x-request-time");return t&&console.log("Pong:",performance.now()-Number(t),"ms"),e}var ae=async function(e){const t=function(e){const t=e.lastIndexOf("#");if(-1===t)throw new Error(`No # found in script url: ${e}`);return e.slice(t+1)}(e),n=new oe(t);let r;window.Mayu=n;const o=document.createElement("mayu-disconnected"),i=document.createElement("mayu-ping");i.setAttribute("region","Connecting..."),i.setAttribute("status","connecting"),document.body.appendChild(i);for await(const[e,n]of X(t))switch(e){case"system.connected":import("./custom-elements/mayu-ping-c498c2a6.js"),import("./custom-elements/mayu-disconnected-9f349f46.js"),import("./custom-elements/mayu-progress-bar-eb3e1ac8.js"),import("./custom-elements/mayu-exception-63df4e8c.js"),import("./custom-elements/mayu-alert-cd7ad2a4.js"),i.setAttribute("region","Connected!"),i.setAttribute("status","connected"),z.success("Connected!"),document.body.querySelectorAll("mayu-disconnected").forEach((e=>e.remove()));break;case"system.disconnected":if(n.transferring){i.setAttribute("region","Transferring…"),i.setAttribute("status","transferring");break}i.setAttribute("region","Disconnected"),i.setAttribute("status","disconnected"),z.error("Disconnected"),o.setAttribute("reason",n.reason),o.parentElement!==document.body&&document.body.appendChild(o);break;case"session.init":await ne,r=new Z(n.ids);break;case"session.patch":r?.apply(n);break;case"session.navigate":const t=n.path;t!==location.pathname&&(z.info("Navigating to",t),history.pushState({},"",t));break;case"session.action":s(n.type,n.payload);break;case"session.keep_alive":break;case"session.transfer":i.setAttribute("region","Transferring"),i.setAttribute("status","transferring");break;case"session.exception":re(n);break;case"ping":const a=Object.values(n.values),c=a.reduce(((e,t)=>e+t),0)/a.length;i.setAttribute("ping",`${c.toFixed(2)} ms`),i.setAttribute("region",`${n.instance} @ ${n.region}`),i.setAttribute("status","ping");break;default:z.warn("Unhandled event:",e,n)}function s(e,t){switch(e){case"scroll_into_view":!function(e,t){const n=document.querySelector(e);n?n.scrollIntoView({block:"start",inline:"nearest",behavior:"smooth",...t}):console.error("Could not find element to scrollIntoView, selector:",e)}(t.selector,t.options||{});break;case"alert":!async function(e){await import("./custom-elements/mayu-alert-cd7ad2a4.js");const t=document.createElement("mayu-alert");t.setAttribute("message",e),document.body.appendChild(t)}(t);break;default:z.error("Unhandled action:",e,t)}}}(import.meta.url);export{ae as default};//# sourceMappingURL=main-8506b35d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-8506b35d.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -114,17 +114,31 @@ function mayuCallback(sessionId: string, handlerId: string, payload: any) {
114
114
  method: "POST",
115
115
  headers: {
116
116
  "content-type": "application/json",
117
+ "x-request-time": performance.now(),
117
118
  },
118
119
  body: JSON.stringify(payload),
119
- });
120
+ }).then(logRequestTime);
120
121
  }
121
122
 
122
123
  async function navigateTo(sessionId: string, url: string) {
123
124
  return fetch(`/__mayu/session/${sessionId}/navigate`, {
124
125
  method: "POST",
125
- headers: { "content-type": "text/plain; charset=utf-8" },
126
+ headers: {
127
+ "content-type": "text/plain; charset=utf-8",
128
+ "x-request-time": performance.now(),
129
+ },
126
130
  body: url,
127
- });
131
+ }).then(logRequestTime);
132
+ }
133
+
134
+ function logRequestTime(res) {
135
+ const requestTime = res.headers.get("x-request-time");
136
+
137
+ if (requestTime) {
138
+ console.log("Pong:", performance.now() - Number(requestTime), "ms");
139
+ }
140
+
141
+ return res;
128
142
  }
129
143
 
130
144
  function getSessionIdFromUrl(url: string) {
@@ -117,7 +117,7 @@ export async function* sessionStream(
117
117
  "ping",
118
118
  {
119
119
  values: {
120
- client: new Date().getTime() - Number(payload.pong),
120
+ client: performance.now() - Number(payload.pong),
121
121
  server: payload.server,
122
122
  },
123
123
  region: payload.region,
@@ -128,7 +128,7 @@ export async function* sessionStream(
128
128
  case "ping":
129
129
  postCallback(sessionId, "ping", {
130
130
  pong: payload,
131
- ping: new Date().getTime(),
131
+ ping: performance.now(),
132
132
  });
133
133
  break;
134
134
  default:
@@ -1,10 +1,9 @@
1
- @layer app\/components\/MyComponent\?ugAGryRB {
1
+ @layer app\/components\/MyComponent\?dn2abQvd {
2
2
  .app\/components\/MyComponent\.foo\?aiQioe1q {
3
3
  color: #f0f;
4
4
  }
5
5
 
6
6
  .app\/components\/MyComponent\.bar\?aiQioe1q {
7
- composes: foo;
8
7
  }
9
8
 
10
9
  }
@@ -74,10 +74,12 @@ module Mayu
74
74
  filename:,
75
75
  output:,
76
76
  layer_name: layer_name,
77
- classes: {
78
- **result.classes.transform_keys(&:to_sym),
79
- **result.elements.transform_keys { :"__#{_1}" }
80
- }.freeze,
77
+ classes:
78
+ join_classes(
79
+ result.classes,
80
+ result.elements,
81
+ result.exports
82
+ ).freeze,
81
83
  elements: result.elements.transform_keys(&:to_sym),
82
84
  content_hash:,
83
85
  source_map: {
@@ -90,6 +92,48 @@ module Mayu
90
92
  )
91
93
  end
92
94
 
95
+ sig do
96
+ params(
97
+ classes: T::Hash[String, String],
98
+ elements: T::Hash[String, String],
99
+ exports: T::Hash[Symbol, T.untyped]
100
+ ).returns(T::Hash[Symbol, String])
101
+ end
102
+ def self.join_classes(classes, elements, exports)
103
+ {
104
+ **classes
105
+ .transform_values { join_class(_1, exports, classes) }
106
+ .transform_keys(&:to_sym),
107
+ **elements
108
+ .transform_values { join_class(_1, exports, classes) }
109
+ .transform_keys { :"__#{_1}" }
110
+ }
111
+ end
112
+
113
+ sig do
114
+ params(
115
+ klass: String,
116
+ exports: T::Hash[Symbol, T.untyped],
117
+ classes: T::Hash[String, String]
118
+ ).returns(String)
119
+ end
120
+ def self.join_class(klass, exports, classes)
121
+ case exports[klass.to_sym]
122
+ in composes:
123
+ [
124
+ klass,
125
+ *composes.map do
126
+ case _1
127
+ in { type: "local", name: }
128
+ classes[name]
129
+ end
130
+ end
131
+ ].join(" ")
132
+ else
133
+ klass
134
+ end
135
+ end
136
+
93
137
  sig { params(str: String).returns(String) }
94
138
  def self.escape_string(str)
95
139
  str.gsub(/[^\w-]/, '\\\\\0')
@@ -248,10 +248,6 @@ module Mayu
248
248
  ping = body["ping"]
249
249
  time = time_ping_value
250
250
  server_pong = time_ping_value - body["pong"].to_f
251
- # Console.logger.info(
252
- # self,
253
- # format("Session #{session.id} ping: %.2f ms", server_pong)
254
- # )
255
251
  headers = {
256
252
  "content-type": "application/json",
257
253
  "set-cookie": set_token_cookie_value(session)
@@ -268,13 +264,22 @@ module Mayu
268
264
  @environment.metrics.session_navigate_count.increment()
269
265
  path = request.read.force_encoding("utf-8")
270
266
  session.handle_callback("navigate", { path: })
267
+ headers = {
268
+ "content-type": "text/plain",
269
+ "set-cookie": set_token_cookie_value(session),
270
+ "x-request-time": request.headers["x-request-time"]
271
+ }
271
272
  Protocol::HTTP::Response[200, headers, ["ok"]]
272
273
  in ["callback", String => callback_id]
273
274
  session.handle_callback(
274
275
  callback_id,
275
276
  JSON.parse(request.read, symbolize_names: true)
276
277
  )
277
- headers = { "set-cookie": set_token_cookie_value(session) }
278
+ headers = {
279
+ "content-type": "text/plain",
280
+ "set-cookie": set_token_cookie_value(session),
281
+ "x-request-time": request.headers["x-request-time"]
282
+ }
278
283
  Protocol::HTTP::Response[200, headers, ["ok"]]
279
284
  end
280
285
  end
data/lib/mayu/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Mayu
5
- VERSION = "0.0.0"
5
+ VERSION = "0.0.1"
6
6
  end
data/mayu-live.gemspec CHANGED
@@ -9,19 +9,20 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ["andreas.alin@gmail.com"]
10
10
 
11
11
  spec.summary = "Server side VDOM framework"
12
- spec.homepage = "https://github.com/mayu-live/framework"
13
12
 
13
+ spec.description = <<~EOF
14
+ Mayu Live is a live streaming server side VirtualDOM framework for Ruby,
15
+ inspired by modern frontend tools that exist in the JavaScript ecosystem.
16
+ EOF
17
+
18
+ spec.homepage = "https://mayu.live/"
14
19
  spec.license = "AGPL-3.0"
15
20
  spec.required_ruby_version = ">= 3.2.0"
16
21
 
17
- # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
18
-
19
22
  spec.metadata["homepage_uri"] = spec.homepage
20
23
  spec.metadata["source_code_uri"] = "https://github.com/mayu-live/framework"
21
24
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
25
 
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
26
  spec.files =
26
27
  Dir.chdir(__dir__) do
27
28
  [
@@ -29,7 +30,12 @@ Gem::Specification.new do |spec|
29
30
  "COPYING",
30
31
  "README.md",
31
32
  *Dir.glob("exe/**/*"),
32
- *Dir.glob("lib/**/*").grep_v("/node_modules").grep_v("/mayu/client/src")
33
+ *Dir.glob("lib/**/*")
34
+ .grep_v("/node_modules")
35
+ .grep_v("/mayu/client/")
36
+ .grep_v("/__test__")
37
+ .grep_v(%r{\.test\.rb\z}),
38
+ *Dir.glob("lib/mayu/client/dist/**/*"),
33
39
  ]
34
40
  end
35
41
  spec.bindir = "exe"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mayu-live
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Alin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-02-08 00:00:00.000000000 Z
11
+ date: 2023-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -374,7 +374,9 @@ dependencies:
374
374
  - - "~>"
375
375
  - !ruby/object:Gem::Version
376
376
  version: 0.1.0
377
- description:
377
+ description: |
378
+ Mayu Live is a live streaming server side VirtualDOM framework for Ruby,
379
+ inspired by modern frontend tools that exist in the JavaScript ecosystem.
378
380
  email:
379
381
  - andreas.alin@gmail.com
380
382
  executables:
@@ -404,10 +406,10 @@ files:
404
406
  - lib/mayu/client/dist/custom-elements/mayu-progress-bar-eb3e1ac8.js
405
407
  - lib/mayu/client/dist/custom-elements/mayu-progress-bar-eb3e1ac8.js.map
406
408
  - lib/mayu/client/dist/entries.json
407
- - lib/mayu/client/dist/main-4b49dbc4.js
408
- - lib/mayu/client/dist/main-4b49dbc4.js.br
409
- - lib/mayu/client/dist/main-4b49dbc4.js.map
410
- - lib/mayu/client/dist/main-4b49dbc4.js.map.br
409
+ - lib/mayu/client/dist/main-8506b35d.js
410
+ - lib/mayu/client/dist/main-8506b35d.js.br
411
+ - lib/mayu/client/dist/main-8506b35d.js.map
412
+ - lib/mayu/client/dist/main-8506b35d.js.map.br
411
413
  - lib/mayu/client/package.json
412
414
  - lib/mayu/client/rollup.config.js
413
415
  - lib/mayu/client/src/DecompressionStream.ts
@@ -454,7 +456,6 @@ files:
454
456
  - lib/mayu/html.rb
455
457
  - lib/mayu/html.yaml
456
458
  - lib/mayu/message_cipher.rb
457
- - lib/mayu/message_cipher.test.rb
458
459
  - lib/mayu/metrics.rb
459
460
  - lib/mayu/metrics/collector.rb
460
461
  - lib/mayu/metrics/exporter.rb
@@ -530,10 +531,8 @@ files:
530
531
  - lib/mayu/resources/transformers/__test__/haml/spacing3.haml
531
532
  - lib/mayu/resources/transformers/__test__/haml/spacing3.rb
532
533
  - lib/mayu/resources/transformers/css.rb
533
- - lib/mayu/resources/transformers/css.test.rb
534
534
  - lib/mayu/resources/transformers/css/rouge_lexer.rb
535
535
  - lib/mayu/resources/transformers/haml.rb
536
- - lib/mayu/resources/transformers/haml.test.rb
537
536
  - lib/mayu/resources/types.rb
538
537
  - lib/mayu/resources/types/README.md
539
538
  - lib/mayu/resources/types/base.rb
@@ -555,7 +554,6 @@ files:
555
554
  - lib/mayu/server/file_server.rb
556
555
  - lib/mayu/session.rb
557
556
  - lib/mayu/state.rb
558
- - lib/mayu/state.test.rb
559
557
  - lib/mayu/state/README.md
560
558
  - lib/mayu/state/action_creator.rb
561
559
  - lib/mayu/state/action_wrapper.rb
@@ -563,32 +561,27 @@ files:
563
561
  - lib/mayu/state/store.rb
564
562
  - lib/mayu/utils.rb
565
563
  - lib/mayu/vdom.rb
566
- - lib/mayu/vdom.test.rb
567
564
  - lib/mayu/vdom/children.rb
568
565
  - lib/mayu/vdom/component_marshaler.rb
569
566
  - lib/mayu/vdom/css_attributes.rb
570
567
  - lib/mayu/vdom/descriptor.rb
571
- - lib/mayu/vdom/descriptor.test.rb
572
568
  - lib/mayu/vdom/dom.rb
573
569
  - lib/mayu/vdom/h.rb
574
570
  - lib/mayu/vdom/id_generator.rb
575
571
  - lib/mayu/vdom/interfaces.rb
576
572
  - lib/mayu/vdom/marshalling.rb
577
573
  - lib/mayu/vdom/reconciliation.rb
578
- - lib/mayu/vdom/reconciliation.test.rb
579
574
  - lib/mayu/vdom/special_elements.rb
580
575
  - lib/mayu/vdom/update_context.rb
581
- - lib/mayu/vdom/vdom.perf.test.rb
582
576
  - lib/mayu/vdom/vnode.rb
583
577
  - lib/mayu/vdom/vtree.rb
584
- - lib/mayu/vdom/vtree.test.rb
585
578
  - lib/mayu/version.rb
586
579
  - mayu-live.gemspec
587
- homepage: https://github.com/mayu-live/framework
580
+ homepage: https://mayu.live/
588
581
  licenses:
589
582
  - AGPL-3.0
590
583
  metadata:
591
- homepage_uri: https://github.com/mayu-live/framework
584
+ homepage_uri: https://mayu.live/
592
585
  source_code_uri: https://github.com/mayu-live/framework
593
586
  post_install_message:
594
587
  rdoc_options: []
@@ -1 +0,0 @@
1
- {"version":3,"file":"main-4b49dbc4.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,16 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
-
6
- require_relative "message_cipher"
7
-
8
- class TestMessageCipher < Minitest::Test
9
- def test_dump_and_load
10
- message_cipher = Mayu::MessageCipher.new(key: "test")
11
-
12
- dumped = message_cipher.dump("hello")
13
- loaded = message_cipher.load(dumped)
14
- assert(loaded == "hello")
15
- end
16
- end
@@ -1,87 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
-
6
- require_relative "css"
7
- require_relative "css/rouge_lexer"
8
- require "rouge"
9
-
10
- class Mayu::Resources::Transformers::CSS::Test < Minitest::Test
11
- EXAMPLES_ROOT = File.join(__dir__, "__test__", "css")
12
-
13
- Dir[File.join(EXAMPLES_ROOT, "*.in.css")].each do |input_path|
14
- basename = File.basename(input_path, ".in.css")
15
-
16
- if ENV["MATCH"] in String => match
17
- next unless basename.include?(match)
18
- end
19
-
20
- skip_path = File.join(EXAMPLES_ROOT, "#{basename}.skip")
21
- output_path = File.join(EXAMPLES_ROOT, "#{basename}.out.css")
22
-
23
- input = File.read(input_path)
24
- expected = File.read(output_path)
25
-
26
- define_method(:"test_#{basename}") do
27
- T.bind(self, Mayu::Resources::Transformers::CSS::Test)
28
-
29
- skip File.read(skip_path) if File.exist?(skip_path)
30
- actual = transform(input)
31
- # File.write(output_path, actual)
32
- assert_equal(expected, actual)
33
- end
34
- end
35
-
36
- private
37
-
38
- def transform(source)
39
- source_path = "app/components/MyComponent"
40
-
41
- Mayu::Resources::Transformers::CSS
42
- .transform(source:, source_path:)
43
- .output
44
- .each_line
45
- .map(&:rstrip)
46
- .join("\n")
47
- .tap do
48
- puts(
49
- "\e[1mTransformed:\e[0m",
50
- prepend_line_numbers(
51
- colorize_source(
52
- _1.strip,
53
- Mayu::Resources::Transformers::CSS::RougeLexer.new
54
- ).each_line
55
- )
56
- )
57
- end
58
- end
59
-
60
- def prepend_line_numbers(lines, start_line: 1, error_line: nil)
61
- number_format = "\e[38;5;250;48;5;236m%3d \e[0m"
62
- error_format = "\e[41m%s\e[0m"
63
-
64
- lines
65
- .map
66
- .with_index(start_line) do |line, i|
67
- if error_line == i
68
- format(error_format, line.chomp) + "\n"
69
- else
70
- line
71
- end.prepend(format(number_format, i))
72
- end
73
- end
74
-
75
- def transform_file(root:, path:)
76
- Mayu::Resources::Transformers::CSS.transform(
77
- source: File.read(File.join(root, path)),
78
- source_path: path
79
- )
80
- end
81
-
82
- def colorize_source(source, lexer)
83
- theme = Rouge::Themes::Monokai.new
84
- formatter = Rouge::Formatters::Terminal256.new(theme:)
85
- formatter.format(lexer.lex(source.chomp))
86
- end
87
- end
@@ -1,114 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
-
6
- require_relative "haml"
7
- require "rouge"
8
-
9
- class TestHaml < Minitest::Test
10
- EXAMPLES_ROOT = File.join(__dir__, "__test__", "haml")
11
-
12
- Dir[File.join(EXAMPLES_ROOT, "*.haml")].each do |input_path|
13
- basename = File.basename(input_path, ".*")
14
-
15
- if ENV["MATCH"] in String => match
16
- next unless basename.include?(match)
17
- end
18
-
19
- skip_path = File.join(EXAMPLES_ROOT, "#{basename}.skip")
20
- output_path = File.join(EXAMPLES_ROOT, "#{basename}.rb")
21
-
22
- input = File.read(input_path)
23
- expected = File.read(output_path)
24
-
25
- define_method(:"test_#{basename}") do
26
- T.bind(self, TestHaml)
27
- skip File.read(skip_path) if File.exist?(skip_path)
28
- actual = transform_and_format(input, path: input_path)
29
- # File.write(output_path, actual)
30
- assert_equal(expected, actual)
31
- end
32
- end
33
-
34
- private
35
-
36
- def transform_and_format_file(root:, path:)
37
- transform_and_format(File.read(File.join(root, path)), path:)
38
- end
39
-
40
- def transform_and_format(
41
- haml,
42
- transform_elements_to_classes: false,
43
- path: nil
44
- )
45
- transformed =
46
- Mayu::Resources::Transformers::Haml.transform(
47
- Mayu::Resources::Transformers::Haml::TransformOptions.new(
48
- source: haml,
49
- source_path: "app/components/MyComponent.haml",
50
- source_line: 1,
51
- content_hash: "abc123",
52
- transform_elements_to_classes:
53
- )
54
- ).output
55
-
56
- puts "\e[1mInput:\e[0;2m #{path}\e[0m"
57
- puts prepend_line_numbers(
58
- colorize_source(haml, Rouge::Lexers::Haml.new).each_line
59
- )
60
- handle_parse_error(transformed) do
61
- formatted = SyntaxTree.format(transformed)
62
- puts "\e[1mOutput:\e[0m"
63
- puts prepend_line_numbers(
64
- colorize_source(formatted, Rouge::Lexers::Ruby).each_line
65
- )
66
- puts
67
- formatted
68
- end
69
- end
70
-
71
- def handle_parse_error(source)
72
- yield
73
- rescue SyntaxTree::Parser::ParseError => e
74
- start_line = [0, 0].max
75
- formatted_source =
76
- prepend_line_numbers(
77
- extract_lines(source.to_s, start_line, -1),
78
- start_line: start_line + 1,
79
- error_line: e.lineno
80
- ).join
81
-
82
- Console.logger.error(self, <<~ERROR)
83
- #{e.message} on line #{e.lineno} col #{e.column}
84
- #{formatted_source}
85
- ERROR
86
-
87
- raise
88
- end
89
-
90
- def extract_lines(str, from, to)
91
- str.each_line.to_a[from..to] || []
92
- end
93
-
94
- def colorize_source(source, lexer)
95
- theme = Rouge::Themes::Monokai.new
96
- formatter = Rouge::Formatters::Terminal256.new(theme:)
97
- formatter.format(lexer.lex(source.chomp))
98
- end
99
-
100
- def prepend_line_numbers(lines, start_line: 1, error_line: nil)
101
- number_format = "\e[38;5;250;48;5;236m%3d \e[0m"
102
- error_format = "\e[41m%s\e[0m"
103
-
104
- lines
105
- .map
106
- .with_index(start_line) do |line, i|
107
- if error_line == i
108
- format(error_format, line.chomp) + "\n"
109
- else
110
- line
111
- end.prepend(format(number_format, i))
112
- end
113
- end
114
- end
@@ -1,97 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
-
6
- require_relative "vdom/descriptor"
7
- require_relative "state"
8
-
9
- class TestState < Minitest::Test
10
- class MyComponent < Mayu::Component::Base
11
- def render
12
- end
13
- end
14
-
15
- State = Mayu::State
16
-
17
- INCREMENT = State::ActionCreator.create(:increment)
18
- DECREMENT = State::ActionCreator.create(:decrement)
19
- ADD_ITEM = State::ActionCreator.create(:add_item)
20
- REMOVE_ITEM = State::ActionCreator.create(:remove_item)
21
- THUNK =
22
- State::ActionCreator.async(:hello) do |store|
23
- store.dispatch(INCREMENT)
24
- sleep 1
25
- store.dispatch(INCREMENT)
26
- sleep 1
27
- store.dispatch(DECREMENT)
28
- end
29
-
30
- def test_initialize_descriptor
31
- Sync do
32
- count_reducer = ->(state, action) do
33
- state ||= { count: 0 }
34
-
35
- case action
36
- when INCREMENT
37
- state.merge(count: state[:count].succ)
38
- when DECREMENT
39
- state.merge(count: state[:count].pred)
40
- else
41
- state
42
- end
43
- end
44
-
45
- totals_reducer = ->(state, action) do
46
- state ||= 0
47
-
48
- case action
49
- in ADD_ITEM
50
- state += 1
51
- in REMOVE_ITEM
52
- state -= 1
53
- else
54
- state
55
- end
56
- end
57
-
58
- items_reducer = ->(state, action) do
59
- state ||= []
60
- p action
61
-
62
- case action
63
- in ADD_ITEM
64
- state + [action[:item]]
65
- in REMOVE_ITEM
66
- state - [action[:item]]
67
- else
68
- state
69
- end
70
- end
71
-
72
- @store =
73
- State::Store.new(
74
- { total: 0, items: [] },
75
- reducers: {
76
- count1: count_reducer,
77
- count2: count_reducer,
78
- items: items_reducer,
79
- totals: totals_reducer
80
- }
81
- )
82
-
83
- @store.dispatch(ADD_ITEM, item: "Apple")
84
- @store.dispatch(ADD_ITEM, item: "Banana")
85
- @store.dispatch(REMOVE_ITEM, item: "Apple")
86
- @store.dispatch(ADD_ITEM, item: "Papaya")
87
- @store.dispatch(INCREMENT)
88
-
89
- puts @store.state
90
- @store.dispatch(THUNK)
91
- sleep 0.1
92
- @store.dispatch(THUNK)
93
- puts "hello"
94
- puts @store.state
95
- end
96
- end
97
- end
@@ -1,26 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
- require_relative "descriptor"
6
-
7
- class TestDescriptor < Minitest::Test
8
- class MyComponent < Mayu::Component::Base
9
- def render
10
- end
11
- end
12
-
13
- def test_element
14
- descriptor = Mayu::VDOM::Descriptor[:foo, key: "test-key"]
15
- assert_equal(descriptor.type, :foo)
16
- assert_equal(descriptor.props, { children: [] })
17
- assert_equal(descriptor.key, "test-key")
18
- end
19
-
20
- def test_component
21
- descriptor = Mayu::VDOM::Descriptor[MyComponent, key: "test-key"]
22
- assert_equal(descriptor.type, MyComponent)
23
- assert_equal(descriptor.props, { children: [] })
24
- assert_equal(descriptor.key, "test-key")
25
- end
26
- end
@@ -1,56 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
- require_relative "../utils"
6
- require_relative "reconciliation"
7
- require_relative "descriptor"
8
- require_relative "h"
9
-
10
- class Mayu::VDOM::Reconciliation::Test < Minitest::Test
11
- class VNode < T::Struct
12
- extend T::Sig
13
- include Mayu::VDOM::Interfaces::VNode
14
-
15
- const :id, String, factory: -> { SecureRandom.alphanumeric(8) }
16
- prop :descriptor, Mayu::VDOM::Descriptor
17
- end
18
-
19
- def test_reconciliation
20
- descriptors = 200.times.map { |i| Mayu::VDOM::H[:li, i.to_s, key: i] }
21
-
22
- patches = []
23
-
24
- vnodes = T.let([], T::Array[VNode])
25
-
26
- p Mayu::Utils.measure_time { vnodes = update(vnodes, descriptors) }
27
-
28
- assert_equal(vnodes.map(&:descriptor), descriptors)
29
-
30
- descriptors = descriptors.shuffle
31
-
32
- p Mayu::Utils.measure_time { vnodes = update(vnodes, descriptors) }
33
-
34
- descriptors = descriptors.shuffle.slice(0..100).to_a
35
-
36
- p Mayu::Utils.measure_time { vnodes = update(vnodes, descriptors) }
37
-
38
- assert_equal(vnodes.map(&:descriptor).map(&:key), descriptors.map(&:key))
39
- end
40
-
41
- def update(vnodes, descriptors)
42
- result =
43
- Mayu::VDOM::Reconciliation.reconcile(vnodes, descriptors) do
44
- case _1
45
- in Mayu::VDOM::Reconciliation::Patches::Init => init
46
- VNode.new(descriptor: init.descriptor)
47
- in Mayu::VDOM::Reconciliation::Patches::Patch => patch
48
- vnode = patch.vnode
49
- vnode.descriptor = patch.descriptor
50
- vnode
51
- end
52
- end
53
- p(count: result.patches.length)
54
- result.vnodes.then { T.cast(_1, T::Array[VNode]) }
55
- end
56
- end
@@ -1,146 +0,0 @@
1
- # typed: false
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
- require "async"
6
- require "rexml/document"
7
- require "stringio"
8
- require "ruby-prof"
9
- require_relative "vtree"
10
- require_relative "h"
11
- require_relative "../session"
12
- require_relative "../commands"
13
- require_relative "../app_metrics"
14
-
15
- class Mayu::VDOM::PerformanceTest < Minitest::Test
16
- H = Mayu::VDOM::H
17
-
18
- class Item < Mayu::Component::Base
19
- def render
20
- H[:li, H[:a, props[:children].to_a, href: props[:path]]]
21
- end
22
- end
23
-
24
- class MyComponent < Mayu::Component::Base
25
- def self.get_initial_state(**props)
26
- { page: 0 }
27
- end
28
-
29
- def handle_next_page(e)
30
- update { |state| { page: state[:page].succ } }
31
- end
32
-
33
- def render
34
- per_page = 50
35
- items = props[:items].slice(state[:page] * per_page, per_page)
36
-
37
- H[
38
- :div,
39
- (H[:button, on_click: handler(:handle_next_page)] unless items.empty?),
40
- H[:ul, items.map { H[Item, _1, key: _1, path: "/#{_1}"] }]
41
- ]
42
- end
43
- end
44
-
45
- def test_perf
46
- items = 2000.times.map { SecureRandom.alphanumeric(5 + rand(10)) }
47
-
48
- Async do
49
- vtree = setup_vtree
50
- app = H[MyComponent, items:]
51
- vtree.render(app)
52
- vtree.to_html.tap { |html| print_xml(html) }
53
-
54
- # https://ruby-prof.github.io/#measurements
55
- RubyProf.measure_mode = RubyProf::WALL_TIME
56
- # RubyProf.measure_mode = RubyProf::PROCESS_TIME
57
- # RubyProf.measure_mode = RubyProf::ALLOCATIONS
58
- # RubyProf.measure_mode = RubyProf::MEMORY
59
-
60
- profile = RubyProf::Profile.new(track_allocations: true)
61
- profile.exclude_methods!(T::Types::Union, :recursively_valid?)
62
- profile.exclude_methods!(T::Types::FixedArray, :initialize)
63
- profile.exclude_methods!(T::Props::WeakConstructor, :initialize)
64
- # profile.exclude_methods!(T::Props::Constructor::DecoratorMethods, :construct_props_without_defaults)
65
- profile.exclude_methods!(T::Types::TypedEnumerable, :recursively_valid?)
66
- # profile.exclude_methods!(T::Private::Methods::Signature, :initialize)
67
-
68
- result =
69
- profile.profile do
70
- while handler_ref =
71
- vtree.instance_variable_get(:@handlers).values.first
72
- handler_ref.call({})
73
- update_vtree(vtree)
74
- end
75
- end
76
-
77
- printer = RubyProf::MultiPrinter.new(result)
78
- path = File.join(Mayu::TestHelper::ROOT, "profile")
79
- FileUtils.mkdir_p(path)
80
- printer.print(path:, profile: File.basename(__FILE__, ".*"))
81
-
82
- vtree.render(app)
83
- vtree.to_html.tap { |html| print_xml(html) }
84
- end
85
- end
86
-
87
- private
88
-
89
- def update_vtree(vtree)
90
- ctx = Mayu::VDOM::UpdateContext.new
91
-
92
- vtree.update_queue.size.times do
93
- case vtree.update_queue.dequeue
94
- in Mayu::VDOM::VNode => vnode
95
- next if vnode.removed?
96
- vtree.patch(ctx, vnode, vnode.descriptor, lifecycles: false)
97
- else
98
- # ok
99
- end
100
- end
101
-
102
- ctx
103
- end
104
-
105
- def setup_vtree
106
- $metrics ||= Mayu::AppMetrics.setup(Prometheus::Client.registry)
107
- config =
108
- Mayu::Configuration.from_hash!(
109
- { "mode" => :test, "root" => "/laiehbaleihf", "secret_key" => "test" }
110
- )
111
- environment = Mayu::Environment.new(config, $metrics)
112
-
113
- environment.instance_eval do
114
- def load_root(path, headers: {})
115
- H[:div]
116
- end
117
- def match_route(path)
118
- end
119
- end
120
-
121
- session = Mayu::Session.new(environment:, path: "/")
122
- Mayu::VDOM::VTree.new(session:)
123
- end
124
-
125
- def print_xml(source)
126
- io = StringIO.new
127
- doc = REXML::Document.new(source)
128
- formatter = REXML::Formatters::Pretty.new
129
- formatter.compact = true
130
- formatter.write(doc, io)
131
- io.rewind
132
-
133
- puts(
134
- io
135
- .read
136
- .to_s
137
- .gsub(/(mayu-id='?)(\d+)/) { "#{$~[1]}\e[1;34m#{$~[2]}\e[0m" }
138
- .gsub(/(mayu-key='?)(\d+)/) { "#{$~[1]}\e[1;35m#{$~[2]}\e[0m" }
139
- .gsub(/>(.*?)</) { ">\e[33m#{$~[1]}\e[0m<" }
140
- )
141
- end
142
-
143
- def extract_numbers(source)
144
- REXML::Document.new(source).get_elements("//li").map(&:text).map(&:to_i)
145
- end
146
- end
@@ -1,68 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
- require "async"
6
- require "rexml/document"
7
- require "stringio"
8
- require_relative "vtree"
9
- require_relative "../session"
10
- require_relative "../app_metrics"
11
-
12
- class TestVTree < Minitest::Test
13
- H = Mayu::VDOM::Descriptor
14
-
15
- MyComponent = Mayu::TestHelper.haml_to_component(__FILE__, __LINE__, <<~HAML)
16
- %div
17
- %h1 Hola mundo #{@lol ||= rand}
18
- %pre= props[:count]
19
- HAML
20
-
21
- def test_component_reuse
22
- Mayu::TestHelper.test_component(MyComponent, count: 0) do |page|
23
- # page.debug!
24
- original_text = page.find_by_css("h1")&.inner_text
25
-
26
- page.render(H[MyComponent, count: 1])
27
- page.wait_for_update
28
- # page.debug!
29
- assert_equal(page.find_by_css("h1")&.inner_text, original_text)
30
-
31
- page.render(H[MyComponent, count: 2])
32
- page.wait_for_update
33
-
34
- # page.debug!
35
- assert_equal(page.find_by_css("h1")&.inner_text, original_text)
36
- end
37
- end
38
-
39
- def test_list_ordering
40
- component = Mayu::TestHelper.haml_to_component(__FILE__, __LINE__, <<~HAML)
41
- %div
42
- %h1 Hello world
43
- %ul
44
- = props[:numbers].map do |num|
45
- %li(key=num)= num
46
- HAML
47
-
48
- number_lists = [
49
- [0, 2, 1, 6, 7, 8, 4, 3, 5],
50
- [1, 7, 6, 5, 3, 0, 2, 4],
51
- [1, 3, 123, 0, 4, 2, 9, 32, 455]
52
- ]
53
-
54
- Mayu::TestHelper.test_component(component, numbers: []) do |page|
55
- number_lists.each do |numbers|
56
- page.render(H[component, numbers:])
57
- assert_equal(numbers, extract_numbers(page.to_html))
58
- # page.debug!
59
- end
60
- end
61
- end
62
-
63
- private
64
-
65
- def extract_numbers(source)
66
- REXML::Document.new(source).get_elements("//li").map(&:text).map(&:to_i)
67
- end
68
- end
@@ -1,73 +0,0 @@
1
- # typed: true
2
-
3
- require "minitest/autorun"
4
- require "test_helper"
5
- require "rouge"
6
- require "nokogiri"
7
- require_relative "resources/transformers/haml"
8
- require_relative "session"
9
- require_relative "vdom"
10
- require_relative "vdom/vtree"
11
-
12
- class Mayu::VDOM::Test < Minitest::Test
13
- MyComponent = Mayu::TestHelper.haml_to_component(__FILE__, __LINE__, <<~HAML)
14
- :ruby
15
- def self.get_initial_state(initial_count: 3, **)
16
- { count: initial_count }
17
- end
18
-
19
- def handle_click(e)
20
- value = e.dig("target", "value").to_i
21
-
22
- update do |state|
23
- { count: state[:count] + value }
24
- end
25
- end
26
-
27
- :css
28
- .foo { color: peru; }
29
- .btn { background: peachpuff; }
30
- .increment { }
31
- .decrement { }
32
- .foo
33
- %button.increment(name="increment" value="1" onclick=handle_click)
34
- Decrement
35
- %button.decrement(name="decrement" value="-1" onclick=handle_click)
36
- Increment
37
- %output= state[:count]
38
- HAML
39
-
40
- def test_vdom
41
- Mayu::TestHelper.test_component(MyComponent) do |page|
42
- button = page.find_by_css("[name=increment]")
43
- page.fire_event(button, :click)
44
- assert_equal(page.find_by_css("output")&.inner_text, "3")
45
- # page.debug!
46
- page.wait_for_update
47
- assert_equal(page.find_by_css("output")&.inner_text, "4")
48
- # page.debug!
49
-
50
- assert_equal(page.to_html, <<~HTML)
51
- <div class="lib/mayu/vdom.foo">
52
- <button
53
- name="increment"
54
- value="1"
55
- onclick="Mayu.handle(event,'LckOTvJsohBty1Pm')"
56
- class="lib/mayu/vdom.increment"
57
- >
58
- Decrement
59
- </button>
60
- <button
61
- name="decrement"
62
- value="-1"
63
- onclick="Mayu.handle(event,'LckOTvJsohBty1Pm')"
64
- class="lib/mayu/vdom.decrement"
65
- >
66
- Increment
67
- </button>
68
- <output>4</output>
69
- </div>
70
- HTML
71
- end
72
- end
73
- end