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 +4 -4
- data/README.md +4 -4
- data/lib/mayu/client/dist/entries.json +1 -1
- data/lib/mayu/client/dist/{main-4b49dbc4.js → main-8506b35d.js} +1 -1
- data/lib/mayu/client/dist/main-8506b35d.js.br +0 -0
- data/lib/mayu/client/dist/main-8506b35d.js.map +1 -0
- data/lib/mayu/client/dist/main-8506b35d.js.map.br +0 -0
- data/lib/mayu/client/src/main.ts +17 -3
- data/lib/mayu/client/src/stream.ts +2 -2
- data/lib/mayu/resources/transformers/__test__/css/composes.out.css +1 -2
- data/lib/mayu/resources/transformers/css.rb +48 -4
- data/lib/mayu/server/app.rb +10 -5
- data/lib/mayu/version.rb +1 -1
- data/mayu-live.gemspec +12 -6
- metadata +11 -18
- data/lib/mayu/client/dist/main-4b49dbc4.js.br +0 -0
- data/lib/mayu/client/dist/main-4b49dbc4.js.map +0 -1
- data/lib/mayu/client/dist/main-4b49dbc4.js.map.br +0 -0
- data/lib/mayu/message_cipher.test.rb +0 -16
- data/lib/mayu/resources/transformers/css.test.rb +0 -87
- data/lib/mayu/resources/transformers/haml.test.rb +0 -114
- data/lib/mayu/state.test.rb +0 -97
- data/lib/mayu/vdom/descriptor.test.rb +0 -26
- data/lib/mayu/vdom/reconciliation.test.rb +0 -56
- data/lib/mayu/vdom/vdom.perf.test.rb +0 -146
- data/lib/mayu/vdom/vtree.test.rb +0 -68
- data/lib/mayu/vdom.test.rb +0 -73
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 735436aabe452e5ddc5aa389289914f6c61a291e4dd0181c8f73623dd0cb4de0
|
4
|
+
data.tar.gz: 7fc97738ce43ffbec5914ec9f20424431b09a2dac0f3ff17f2ff77eec0d380ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
[](https://github.com/mayu-live/framework/actions/workflows/test.yml)
|
4
|
+
[](https://github.com/mayu-live/framework/releases)
|
5
5
|
[](https://github.com/mayu-live/framework/commits)
|
6
6
|
[](https://github.com/mayu-live/framework/blob/main/COPYING) 
|
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
|
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
|
220
|
+
Class names are applied automatically.
|
221
221
|
|
222
222
|
### `app/components/Example.haml`
|
223
223
|
|
@@ -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
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"main-8506b35d.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
Binary file
|
data/lib/mayu/client/src/main.ts
CHANGED
@@ -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: {
|
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:
|
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:
|
131
|
+
ping: performance.now(),
|
132
132
|
});
|
133
133
|
break;
|
134
134
|
default:
|
@@ -74,10 +74,12 @@ module Mayu
|
|
74
74
|
filename:,
|
75
75
|
output:,
|
76
76
|
layer_name: layer_name,
|
77
|
-
classes:
|
78
|
-
|
79
|
-
|
80
|
-
|
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')
|
data/lib/mayu/server/app.rb
CHANGED
@@ -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 = {
|
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
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/**/*")
|
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.
|
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-
|
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-
|
408
|
-
- lib/mayu/client/dist/main-
|
409
|
-
- lib/mayu/client/dist/main-
|
410
|
-
- lib/mayu/client/dist/main-
|
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://
|
580
|
+
homepage: https://mayu.live/
|
588
581
|
licenses:
|
589
582
|
- AGPL-3.0
|
590
583
|
metadata:
|
591
|
-
homepage_uri: https://
|
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: []
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"main-4b49dbc4.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
Binary file
|
@@ -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
|
data/lib/mayu/state.test.rb
DELETED
@@ -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
|
data/lib/mayu/vdom/vtree.test.rb
DELETED
@@ -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
|
data/lib/mayu/vdom.test.rb
DELETED
@@ -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
|