turbo_boost-commands 0.0.18 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 342917e85cc7c292f5a8291685144003787e2c7160bff7efd99201d4ccf3b79b
4
- data.tar.gz: 1f56a0a3556b021e07cb7431a2322b1aa5b7f410f4a128009d2c78f8d2f8aa4f
3
+ metadata.gz: fe57415eb98233d7d79fe4ecf5233c0b66dd55d5fd31e6145b65239a2610ca59
4
+ data.tar.gz: ec22902b18229231a34782f84444a9f1105295cb4097c0b4c2302638cc059e00
5
5
  SHA512:
6
- metadata.gz: 28129732bad9aa2621714b0e3ea7714d2f096075f61594e7d331343ac45a2741db02a9fb849a5355e1b033038bb7a85f6c3b16bd2be7ac8f42e2b14f6ea2093e
7
- data.tar.gz: 3b1088f768fcab89de2bdb4ebf65c3b36d4db675b42b01e0bf3bc16ec445c716f5aafa3cfc00ad8d448249bed00e5bf553cd942e0b9a13a6516a1a1d014b71e3
6
+ metadata.gz: 9a681c972bda8d1eac7046c72b51e08e888aa227d63d7d5f30cf90b026008de270cc6981e19d54dcf5402d4605c300c109da1f004ffc270d85a348793f4237bc
7
+ data.tar.gz: efd2bb9c417f5c6b062708fcabfcbc38506912bc9fc8a3d75fea418520d8bd043bdc270b01d2beeb8f8d24086581c14074129a20d2c5b10b112afe08996aa515
data/README.md CHANGED
@@ -131,10 +131,12 @@ Commands can be tested in isolation as well as with standard Rails controller, i
131
131
 
132
132
  ## Dependencies
133
133
 
134
- - [rails](https://rubygems.org/gems/rails) `>=6.1`
135
- - [turbo-rails](https://rubygems.org/gems/turbo-rails) `>=1.1`
136
- - [@hotwired/turbo-rails](https://yarnpkg.com/package/@hotwired/turbo-rails) `>=7.1`
137
- - [ruby](https://github.com/ruby/ruby) `>=2.7`
134
+ - [rails](https://rubygems.org/gems/rails) `>= 6.1`
135
+ - [turbo-rails](https://rubygems.org/gems/turbo-rails) `>= 1.1`
136
+ - [@hotwired/turbo-rails](https://www.npmjs.com/package/@hotwired/turbo-rails) `>= 7.2`
137
+ - [alpinejs](https://www.npmjs.com/package/alpinejs) `>= 3.13`
138
+ - [@alpinejs/morph](https://www.npmjs.com/package/@alpinejs/morph) `>= 3.13`
139
+ - [@turbo-boost/streams](https://www.npmjs.com/package/@turbo-boost/streams) `>= 0.1.7`
138
140
 
139
141
  ## Setup
140
142
 
@@ -169,19 +171,6 @@ rails app:template LOCATION='https://railsbytes.com/script/xkjsbB'
169
171
  +import '@turbo-boost/commands'
170
172
  ```
171
173
 
172
- 3. Add TurboBoost to your Rails app
173
-
174
- ```diff
175
- # app/views/layouts/application.html.erb
176
- <html>
177
- <head>
178
- + <%= turbo_boost.meta_tag %>
179
- </head>
180
- <body>
181
- </body>
182
- </html>
183
- ```
184
-
185
174
  ## Usage
186
175
 
187
176
  This example illustrates how to use TurboBoost Commands to manage upvotes on a Post.
@@ -556,14 +545,19 @@ fly deploy
556
545
 
557
546
  ## Releasing
558
547
 
559
- 1. Run `yarn` and `bundle` to pick up the latest
548
+ > [!TIP]
549
+ > Run these commands on the host machine _(i.e. not inside the dev container)_
550
+
551
+ 1. Run `npm update` and `bundle update` to pick up the latest dependencies
560
552
  1. Bump version number at `lib/turbo_boost-streams/version.rb`. Pre-release versions use `.preN`
561
553
  1. Bump version number at `package.json` _(make sure it matches)_. Pre-release versions use `-preN`
562
- 1. Run `yarn build` and `rake build`
563
- 1. Commit and push changes to GitHub
554
+ 1. Run `bin/standardize`
555
+ 1. Run `rake build`
556
+ 1. Run `npm run build`
557
+ 1. Commit and push any changes to GitHub
564
558
  1. Run `rake release`
565
- 1. Run `yarn publish --no-git-tag-version --access public --new-version X.X.X` _(use same version number)_
566
- 1. Create a new release on GitHub ([here](https://github.com/hopsoft/turbo_boost-streams/releases)) and generate the changelog for the stable release for it
559
+ 1. Run `npm publish --access public`
560
+ 1. Create a new release on GitHub ([here](https://github.com/hopsoft/turbo_boost-commands/releases)) and generate the changelog for the stable release for it
567
561
 
568
562
  ## About TurboBoost
569
563
 
@@ -1,2 +1,2 @@
1
- var Z=Object.defineProperty,ee=Object.defineProperties;var te=Object.getOwnPropertyDescriptors;var I=Object.getOwnPropertySymbols;var re=Object.prototype.hasOwnProperty,oe=Object.prototype.propertyIsEnumerable;var X=(e,t,r)=>t in e?Z(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,s=(e,t)=>{for(var r in t||(t={}))re.call(t,r)&&X(e,r,t[r]);if(I)for(var r of I(t))oe.call(t,r)&&X(e,r,t[r]);return e},u=(e,t)=>ee(e,te(t));var O=class{get element(){return document.querySelector('meta[name="turbo-boost"]')}get token(){return this.element.getAttribute("content")}get busy(){return this.element.dataset.busy==="true"}set busy(t){return this.element.dataset.busy=!!t}},a=new O;var i={start:"turbo-boost:command:start",success:"turbo-boost:command:success",finish:"turbo-boost:command:finish",abort:"turbo-boost:command:abort",clientError:"turbo-boost:command:client-error",serverError:"turbo-boost:command:server-error"},l={stateLoad:"turbo-boost:state:load",stateChange:"turbo-boost:state:change"},f=s(s({},i),l);function d(e,t,r={}){return new Promise(o=>{r=r||{},r.detail=r.detail||{},t=t||document;let n=new CustomEvent(e,u(s({},r),{bubbles:!0}));t.dispatchEvent(n),o(n)})}var B;function k(e,t=null){if(!e||typeof e!="object")return e;let r=new Proxy(e,{deleteProperty(o,n){return delete o[n],d(l.stateChange,a.element,{detail:{state:B}}),!0},set(o,n,c,A){return o[n]=k(c,this),d(l.stateChange,a.element,{detail:{state:B}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=k(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=k(n,r);return t||(B=r),r}var F=k;var D,v,C,N;function J(){if(!a.element)return g();let e=atob(a.element.dataset.state);C={},v=F(JSON.parse(e)),D=s({},v),delete a.element.dataset.clientStateChange,setTimeout(()=>d(l.stateLoad,a.element,{detail:{state:v}}))}function g(){clearTimeout(N),N=setTimeout(J,10)}D||J();addEventListener("DOMContentLoaded",g);addEventListener("load",g);addEventListener("turbo:load",g);addEventListener("turbo:frame-load",g);addEventListener(i.success,g);addEventListener(l.stateChange,e=>{C={};for(let[t,r]of Object.entries(v))D[t]!==r&&(C[t]=r);a.element.dataset.clientStateChange=!0,a.element.dataset.state=btoa(JSON.stringify(v))});var h={events:l,get current(){return v},get delta(){return C},get payloadChunks(){return btoa(JSON.stringify(C)).match(/.{1,2000}/g)}};function ne(e){let t="<html",r="</html",o=e.indexOf(t),n=e.lastIndexOf(r);if(o>=0&&n>=0){let c=e.slice(e.indexOf(">",o)+1,n);document.documentElement.innerHTML=c}}function se(e){document.body.insertAdjacentHTML("beforeend",e)}var E={append:se,replaceDocument:ne};var L={};function ae(e){L[e.id]=e}function ie(e){delete L[e]}var S={add:ae,remove:ie,get commands(){return[...Object.values(L)]},get length(){return Object.keys(L).length}};function M(e){e.detail.endedAt=Date.now(),e.detail.milliseconds=e.detail.endedAt-e.detail.startedAt,setTimeout(()=>d(i.finish,e.target,{detail:e.detail}),25)}addEventListener(i.serverError,M);addEventListener(i.success,M);addEventListener(i.finish,e=>S.remove(e.detail.id),!0);var T={events:i};var R={};addEventListener("turbo:before-fetch-request",e=>{let t=e.target.closest("turbo-frame"),{fetchOptions:r}=e.detail;if(a.busy){let o=["text/vnd.turbo-boost.html",r.headers.Accept];o=o.filter(n=>n&&n.trim().length>0).join(", "),r.headers.Accept=o,r.headers["TurboBoost-Token"]=a.token}h.payloadChunks.forEach((o,n)=>{r.headers[`TurboBoost-State-${n.toString().padStart(4,"0")}`]=o})});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(R[t.id]=t.src),r.header("TurboBoost")){if(r.statusCode<200||r.statusCode>399){let o=`Server returned a ${r.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`;d(T.events.clientError,document,{detail:u(s({},e.detail),{error:o})},!0)}r.header("TurboBoost")==="Append"&&(e.preventDefault(),r.responseText.then(o=>E.append(o)))}});addEventListener("turbo:frame-load",e=>{let t=e.target.closest("turbo-frame");t.dataset.turboBoostSrc=R[t.id]||t.src||t.dataset.turboBoostSrc,delete R[t.id]});var de={frameAttribute:"data-turbo-frame",methodAttribute:"data-turbo-method",commandAttribute:"data-turbo-command",confirmAttribute:"data-turbo-confirm"},m=s({},de);var j={method:e=>Promise.resolve(confirm(e))},me=e=>e.detail.driver==="method",ue=e=>{if(e.detail.driver!=="form")return!1;let t=e.target,r=t.closest("turbo-frame"),o=t.closest(`[${m.frameAttribute}]`);return!!(r||o)},ce=e=>me(e)||ue(e);document.addEventListener(i.start,async e=>{let t=e.target.getAttribute(m.confirmAttribute);if(!t||(e.detail.confirmation=!0,ce(e)))return;await j.method(t)||e.preventDefault()});var W=j;var b=[],$;function le(e,t){let r=b.find(o=>o.name===e);return r&&b.splice(b.indexOf(r),1),b=[{name:e,selectors:t},...b],document.removeEventListener(e,$,!0),document.addEventListener(e,$,!0),s({},b.find(o=>o.name===e))}function fe(e){return b.find(t=>t.selectors.find(r=>Array.from(document.querySelectorAll(r)).find(o=>o===e)))}function be(e,t){let r=fe(t);return r&&r.name===e}var p={register:le,isRegisteredForElement:be,get events(){return[...b]},set handler(e){$=e}};function pe(e){return e.closest(`[${m.commandAttribute}]`)}function he(e){return e.closest("turbo-frame[src]")||e.closest("turbo-frame[data-turbo-frame-src]")||e.closest("turbo-frame")}function ve(e,t={}){if(e.tagName.toLowerCase()!=="select")return t.value=e.value||null;if(!e.multiple)return t.value=e.options[e.selectedIndex].value;t.values=Array.from(e.options).reduce((r,o)=>(o.selected&&r.push(o.value),r),[])}function ge(e){let t=Array.from(e.attributes).reduce((r,o)=>{let n=o.value;return r[o.name]=n,r},{});return t.tag=e.tagName,t.checked=!!e.checked,t.disabled=!!e.disabled,ve(e,t),delete t.class,delete t.action,delete t.href,delete t[m.commandAttribute],delete t[m.frameAttribute],t}var y={buildAttributePayload:ge,findClosestCommand:pe,findClosestFrameWithSource:he};function Ee(e,t={},r={}){t.token=a.token;let o=e.querySelector('input[name="turbo_boost_command"]')||document.createElement("input");o.type="hidden",o.name="turbo_boost_command",o.value=JSON.stringify(t),e.appendChild(o)}var U={invokeCommand:Ee};function xe(e,t={}){let r=document.createElement("a");r.href=e;let o=new URL(r);return o.searchParams.set("turbo_boost_command",JSON.stringify(t)),o}var x={build:xe};function Ce(e,t){let r=t.src;t=s({},t),delete t.src,e.src=x.build(r,t)}var H={invokeCommand:Ce};function Te(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",x.build(r,t))}var V={invokeCommand:Te};function ye(e){let t=e.target;d(T.events.abort,document,{detail:u(s({},e.detail),{xhr:t})})}function P(e){let t=e.target;(t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html"))&&E.append(t.responseText);let o=`Server returned a ${t.status} status code! TurboBoost Commands require 2XX-3XX status codes.`;d(T.events.clientError,document,{detail:u(s({},e.detail),{error:o,xhr:t})},!0)}function Ae(e){let t=e.target;if(t.status<200||t.status>399)return P(e);let r=t.responseText;t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html")?E.append(t.responseText):E.replaceDocument(t.responseText)}function ke(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",x.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.setRequestHeader("TurboBoost-Token",a.token),h.payloadChunks.forEach((o,n)=>r.setRequestHeader(`TurboBoost-State-${n.toString().padStart(4,"0")}`,o)),r.addEventListener("abort",ye),r.addEventListener("error",P),r.addEventListener("load",Ae),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;P(r,{detail:{message:o}})}}var G={invokeCommand:ke};function q(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Le(e){let t=y.findClosestFrameWithSource(e),{turboFrame:r,turboMethod:o}=e.dataset;return e.tagName.toLowerCase()==="form"?{name:"form",reason:"Element is a form.",frame:t,src:e.action,invokeCommand:U.invokeCommand}:o&&o.length>0?{name:"method",reason:"Element defines data-turbo-method.",frame:t,src:e.href,invokeCommand:V.invokeCommand}:r&&r!=="_self"?(t=document.getElementById(r),{name:"frame",reason:"element targets a frame that is not _self",frame:t,src:q(e,t),invokeCommand:H.invokeCommand}):(!r||r==="_self")&&t?{name:"frame",reason:"element does NOT target a frame or targets _self and is contained by a frame",frame:t,src:q(e,t),invokeCommand:H.invokeCommand}:{name:"window",reason:"element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)",frame:null,src:q(e),invokeCommand:G.invokeCommand}}var _={find:Le};var w="unknown",z={debug:Object.values(f),info:Object.values(f),warn:[f.abort,f.clientError,f.serverError],error:[f.clientError,f.serverError],unknown:[]};Object.values(f).forEach(e=>{addEventListener(e,t=>{if(z[w].includes(t.type)){let{target:r,detail:o}=t;console[w](t.type,{target:r,detail:o})}})});var K={get level(){return w},set level(e){return Object.keys(z).includes(e)||(e="unknown"),w=e}};function Se(){return("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}var Q={v4:Se};function Y(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:y.buildAttributePayload(t),startedAt:Date.now()}}async function we(e){let t,r={};try{if(t=y.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${Q.v4()}`,n=_.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),A=await d(i.start,t,{cancelable:!0,detail:c});if(A.defaultPrevented||A.detail.confirmation&&e.defaultPrevented)return d(i.abort,t,{detail:{message:`An event handler for '${i.start}' prevented default behavior and blocked command invocation!`,source:A}});switch(n=_.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),S.add(c),["frame","window"].includes(n.name)&&e.preventDefault(),a.busy=!0,setTimeout(()=>a.busy=!1,10),n.name){case"method":return n.invokeCommand(t,c);case"form":return n.invokeCommand(t,c,e);case"frame":return n.invokeCommand(n.frame,c);case"window":return n.invokeCommand(c)}}catch(o){d(i.clientError,t,{detail:u(s({},r),{error:o})})}}self.TurboBoost=self.TurboBoost||{};self.TurboBoost=u(s({},self.TurboBoost),{stateEvents:l,get state(){return h.current},get stateDelta(){return h.delta}});self.TurboBoost.Commands||(p.handler=we,p.register("click",[`[${m.commandAttribute}]`]),p.register("submit",[`form[${m.commandAttribute}]`]),p.register("change",[`input[${m.commandAttribute}]`,`select[${m.commandAttribute}]`,`textarea[${m.commandAttribute}]`]),self.TurboBoost.Commands={confirmation:W,logger:K,schema:m,events:i,registerEventDelegate:p.register,get eventDelegates(){return p.events}});var Qt=self.TurboBoost.Commands;export{Qt as default};
1
+ var K=Object.defineProperty,Q=Object.defineProperties;var Y=Object.getOwnPropertyDescriptors;var I=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var X=(e,t,r)=>t in e?K(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,s=(e,t)=>{for(var r in t||(t={}))Z.call(t,r)&&X(e,r,t[r]);if(I)for(var r of I(t))ee.call(t,r)&&X(e,r,t[r]);return e},c=(e,t)=>Q(e,Y(t));var d={start:"turbo-boost:command:start",success:"turbo-boost:command:success",finish:"turbo-boost:command:finish",abort:"turbo-boost:command:abort",clientError:"turbo-boost:command:client-error",serverError:"turbo-boost:command:server-error"},f={stateLoad:"turbo-boost:state:load",stateChange:"turbo-boost:state:change"},u=s(s({},d),f);function a(e,t,r={}){return new Promise(o=>{r=r||{},r.detail=r.detail||{},t=t||document;let n=new CustomEvent(e,c(s({},r),{bubbles:!0}));t.dispatchEvent(n),o(n)})}var L;function C(e,t=null){if(!e||typeof e!="object")return e;let r=new Proxy(e,{deleteProperty(o,n){return delete o[n],a(f.stateChange,document,{detail:{state:L}}),!0},set(o,n,i,b){return o[n]=C(i,this),a(f.stateChange,document,{detail:{state:L}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=C(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=C(n,r);return t||(L=r),r}var _=C;var S,A,O,q;function te(e,t){let r=JSON.parse(e);S=s({},r),q=t,A=_(r),O={},setTimeout(()=>a(f.stateLoad,document,{detail:{state:A}}))}addEventListener(f.stateChange,e=>{for(let[t,r]of Object.entries(A))S[t]!==r&&(O[t]=r)});var y={initialize:te,events:f,get initial(){return S},get current(){return A},get changed(){return O},get signed(){return q}};function re(e){let t="<html",r="</html",o=e.indexOf(t),n=e.lastIndexOf(r);if(o>=0&&n>=0){let i=e.slice(e.indexOf(">",o)+1,n);document.documentElement.innerHTML=i}}function oe(e){document.body.insertAdjacentHTML("beforeend",e)}var h={append:oe,replaceDocument:re};var T={};function ne(e){T[e.id]=e}function se(e){delete T[e]}var k={add:ne,remove:se,get commands(){return[...Object.values(T)]},get length(){return Object.keys(T).length}};function F(e){e.detail.endedAt=Date.now(),e.detail.milliseconds=e.detail.endedAt-e.detail.startedAt,setTimeout(()=>a(d.finish,e.target,{detail:e.detail}),25)}addEventListener(d.serverError,F);addEventListener(d.success,F);addEventListener(d.finish,e=>k.remove(e.detail.id),!0);var g={events:d};var B={};addEventListener("turbo:before-fetch-request",e=>{var o,n;let t=e.target.closest("turbo-frame"),{fetchOptions:r}=e.detail;if((n=(o=self.TurboBoost)==null?void 0:o.Commands)!=null&&n.busy){let i=["text/vnd.turbo-boost.html",r.headers.Accept];i=i.filter(b=>b&&b.trim().length>0).join(", "),r.headers.Accept=i}});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(B[t.id]=t.src),r.header("TurboBoost")){if(r.statusCode<200||r.statusCode>399){let o=`Server returned a ${r.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`;a(g.events.clientError,document,{detail:c(s({},e.detail),{error:o})},!0)}r.header("TurboBoost")==="Append"&&(e.preventDefault(),r.responseText.then(o=>h.append(o)))}});addEventListener("turbo:frame-load",e=>{let t=e.target.closest("turbo-frame");t.dataset.turboBoostSrc=B[t.id]||t.src||t.dataset.turboBoostSrc,delete B[t.id]});var ae={frameAttribute:"data-turbo-frame",methodAttribute:"data-turbo-method",commandAttribute:"data-turbo-command",confirmAttribute:"data-turbo-confirm"},m=s({},ae);var M={method:e=>Promise.resolve(confirm(e))},ie=e=>e.detail.driver==="method",de=e=>{if(e.detail.driver!=="form")return!1;let t=e.target,r=t.closest("turbo-frame"),o=t.closest(`[${m.frameAttribute}]`);return!!(r||o)},me=e=>ie(e)||de(e);document.addEventListener(d.start,async e=>{let t=e.target.getAttribute(m.confirmAttribute);if(!t||(e.detail.confirmation=!0,me(e)))return;await M.method(t)||e.preventDefault()});var N=M;var l=[],D;function ce(e,t){let r=l.find(o=>o.name===e);return r&&l.splice(l.indexOf(r),1),l=[{name:e,selectors:t},...l],document.removeEventListener(e,D,!0),document.addEventListener(e,D,!0),s({},l.find(o=>o.name===e))}function ue(e){return l.find(t=>t.selectors.find(r=>Array.from(document.querySelectorAll(r)).find(o=>o===e)))}function fe(e,t){let r=ue(t);return r&&r.name===e}var p={register:ce,isRegisteredForElement:fe,get events(){return[...l]},set handler(e){D=e}};function le(e){return e.closest(`[${m.commandAttribute}]`)}function pe(e){return e.closest("turbo-frame[src]")||e.closest("turbo-frame[data-turbo-frame-src]")||e.closest("turbo-frame")}function be(e,t={}){if(e.tagName.toLowerCase()!=="select")return t.value=e.value||null;if(!e.multiple)return t.value=e.options[e.selectedIndex].value;t.values=Array.from(e.options).reduce((r,o)=>(o.selected&&r.push(o.value),r),[])}function he(e){let t=Array.from(e.attributes).reduce((r,o)=>{let n=o.value;return r[o.name]=n,r},{});return t.tag=e.tagName,t.checked=!!e.checked,t.disabled=!!e.disabled,be(e,t),delete t.class,delete t.action,delete t.href,delete t[m.commandAttribute],delete t[m.frameAttribute],t}var E={buildAttributePayload:he,findClosestCommand:le,findClosestFrameWithSource:pe};function ve(e,t={},r={}){let o=e.querySelector('input[name="turbo_boost_command"]')||document.createElement("input");o.type="hidden",o.name="turbo_boost_command",o.value=JSON.stringify(t),e.appendChild(o)}var j={invokeCommand:ve};function ge(e,t={}){let r=document.createElement("a");r.href=e;let o=new URL(r);return o.searchParams.set("tbc",JSON.stringify(t)),o}var v={build:ge};function Ee(e,t){let r=t.src;t=s({},t),delete t.src,e.src=v.build(r,t)}var P={invokeCommand:Ee};function xe(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",v.build(r,t))}var W={invokeCommand:xe};function Ce(e){let t=e.target;a(g.events.abort,document,{detail:c(s({},e.detail),{xhr:t})})}function R(e){let t=e.target;(t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html"))&&h.append(t.responseText);let o=`Server returned a ${t.status} status code! TurboBoost Commands require 2XX-3XX status codes.`;a(g.events.clientError,document,{detail:c(s({},e.detail),{error:o,xhr:t})},!0)}function Ae(e){let t=e.target;if(t.status<200||t.status>399)return R(e);let r=t.responseText;t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html")?h.append(t.responseText):h.replaceDocument(t.responseText)}function ye(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",v.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.addEventListener("abort",Ce),r.addEventListener("error",R),r.addEventListener("load",Ae),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;R(r,{detail:{message:o}})}}var J={invokeCommand:ye};function $(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Te(e){let t=E.findClosestFrameWithSource(e),{turboFrame:r,turboMethod:o}=e.dataset;return e.tagName.toLowerCase()==="form"?{name:"form",reason:"Element is a form.",frame:t,src:e.action,invokeCommand:j.invokeCommand}:o&&o.length>0?{name:"method",reason:"Element defines data-turbo-method.",frame:t,src:e.href,invokeCommand:W.invokeCommand}:r&&r!=="_self"?(t=document.getElementById(r),{name:"frame",reason:"element targets a frame that is not _self",frame:t,src:$(e,t),invokeCommand:P.invokeCommand}):(!r||r==="_self")&&t?{name:"frame",reason:"element does NOT target a frame or targets _self and is contained by a frame",frame:t,src:$(e,t),invokeCommand:P.invokeCommand}:{name:"window",reason:"element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)",frame:null,src:$(e),invokeCommand:J.invokeCommand}}var H={find:Te};var w="unknown",U={debug:Object.values(u),info:Object.values(u),warn:[u.abort,u.clientError,u.serverError],error:[u.clientError,u.serverError],unknown:[]};Object.values(u).forEach(e=>{addEventListener(e,t=>{if(U[w].includes(t.type)){let{target:r,detail:o}=t;console[w](t.type,{target:r,detail:o})}})});var V={get level(){return w},set level(e){return Object.keys(U).includes(e)||(e="unknown"),w=e}};function ke(){return("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}var z={v4:ke};var we=self.TurboBoost||{},x={busy:!1,confirmation:N,logger:V,schema:m,events:d,registerEventDelegate:p.register,get eventDelegates(){return p.events}};function G(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:E.buildAttributePayload(t),startedAt:Date.now(),token:x.token,signedState:y.signed,clientState:y.changed}}async function Le(e){let t,r={};try{if(t=E.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${z.v4()}`,n=H.find(t),i=c(s({},G(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),b=await a(d.start,t,{cancelable:!0,detail:i});if(b.defaultPrevented||b.detail.confirmation&&e.defaultPrevented)return a(d.abort,t,{detail:{message:`An event handler for '${d.start}' prevented default behavior and blocked command invocation!`,source:b}});switch(n=H.find(t),i=c(s({},G(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),k.add(i),["frame","window"].includes(n.name)&&e.preventDefault(),x.busy=!0,setTimeout(()=>x.busy=!1,10),n.name){case"method":return n.invokeCommand(t,i);case"form":return n.invokeCommand(t,i,e);case"frame":return n.invokeCommand(n.frame,i);case"window":return n.invokeCommand(i)}}catch(o){a(d.clientError,t,{detail:c(s({},r),{error:o})})}}self.TurboBoost=s({},we);self.TurboBoost.Commands||(p.handler=Le,p.register("click",[`[${m.commandAttribute}]`]),p.register("submit",[`form[${m.commandAttribute}]`]),p.register("change",[`input[${m.commandAttribute}]`,`select[${m.commandAttribute}]`,`textarea[${m.commandAttribute}]`]),self.TurboBoost.Commands=x,self.TurboBoost.State=y);var Ut=x;export{Ut as default};
2
2
  //# sourceMappingURL=commands.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../javascript/meta.js", "../../../javascript/events.js", "../../../javascript/state/observable.js", "../../../javascript/state/index.js", "../../../javascript/renderer.js", "../../../javascript/activity.js", "../../../javascript/lifecycle.js", "../../../javascript/turbo.js", "../../../javascript/schema.js", "../../../javascript/confirmation.js", "../../../javascript/delegates.js", "../../../javascript/elements.js", "../../../javascript/drivers/form.js", "../../../javascript/urls.js", "../../../javascript/drivers/frame.js", "../../../javascript/drivers/method.js", "../../../javascript/drivers/window.js", "../../../javascript/drivers/index.js", "../../../javascript/logger.js", "../../../javascript/uuids.js", "../../../javascript/index.js"],
4
- "sourcesContent": ["class Meta {\n get element() {\n return document.querySelector('meta[name=\"turbo-boost\"]')\n }\n\n get token() {\n return this.element.getAttribute('content')\n }\n\n get busy() {\n return this.element.dataset.busy === 'true'\n }\n\n set busy(value) {\n return (this.element.dataset.busy = !!value)\n }\n}\n\nexport default new Meta()\n", "export const commandEvents = {\n start: 'turbo-boost:command:start',\n success: 'turbo-boost:command:success',\n finish: 'turbo-boost:command:finish',\n abort: 'turbo-boost:command:abort',\n clientError: 'turbo-boost:command:client-error',\n serverError: 'turbo-boost:command:server-error'\n}\n\nexport const stateEvents = {\n stateLoad: 'turbo-boost:state:load',\n stateChange: 'turbo-boost:state:change'\n}\n\nexport const allEvents = { ...commandEvents, ...stateEvents }\n\nexport function dispatch(name, target, options = {}) {\n return new Promise(resolve => {\n options = options || {}\n options.detail = options.detail || {}\n target = target || document\n const evt = new CustomEvent(name, { ...options, bubbles: true })\n target.dispatchEvent(evt)\n resolve(evt)\n })\n}\n", "import meta from '../meta'\nimport { dispatch, stateEvents as events } from '../events'\n\nlet head\n\nfunction observable(object, parent = null) {\n if (!object || typeof object !== 'object') return object\n\n const proxy = new Proxy(object, {\n deleteProperty(target, key) {\n delete target[key]\n dispatch(events.stateChange, meta.element, { detail: { state: head } })\n return true\n },\n\n set(target, key, value, receiver) {\n target[key] = observable(value, this)\n dispatch(events.stateChange, meta.element, { detail: { state: head } })\n return true\n }\n })\n\n if (Array.isArray(object)) {\n object.forEach((value, index) => (object[index] = observable(value, proxy)))\n } else if (typeof object === 'object') {\n for (const [key, value] of Object.entries(object)) object[key] = observable(value, proxy)\n }\n\n if (!parent) head = proxy\n return proxy\n}\n\nexport default observable\n", "import meta from '../meta'\nimport observable from './observable'\nimport { dispatch, commandEvents, stateEvents } from '../events'\n\nlet loadedState, currentState, changedState\nlet loadStateTimeout\n\nfunction loadState() {\n if (!meta.element) return loadStateLater()\n const json = atob(meta.element.dataset.state)\n changedState = {}\n currentState = observable(JSON.parse(json))\n loadedState = { ...currentState }\n delete meta.element.dataset.clientStateChange\n setTimeout(() =>\n dispatch(stateEvents.stateLoad, meta.element, {\n detail: { state: currentState }\n })\n )\n}\n\nfunction loadStateLater() {\n clearTimeout(loadStateTimeout)\n loadStateTimeout = setTimeout(loadState, 10)\n}\n\nif (!loadedState) loadState()\n\naddEventListener('DOMContentLoaded', loadStateLater)\naddEventListener('load', loadStateLater)\naddEventListener('turbo:load', loadStateLater)\naddEventListener('turbo:frame-load', loadStateLater)\naddEventListener(commandEvents.success, loadStateLater)\n\naddEventListener(stateEvents.stateChange, event => {\n changedState = {}\n for (const [key, value] of Object.entries(currentState))\n if (loadedState[key] !== value) changedState[key] = value\n meta.element.dataset.clientStateChange = true\n meta.element.dataset.state = btoa(JSON.stringify(currentState))\n})\n\nexport default {\n events: stateEvents,\n\n get current() {\n return currentState\n },\n\n get delta() {\n return changedState\n },\n\n // The UI state changes are split into chunks and sent to the server in an HTTP request header.\n // Max size for an HTTP header is around 4k or 4,000 bytes.\n // A Base64 character is an 8-bit-padded ASCII character... or 1 byte\n //\n // SEE: lib/state.rb - for info on how `state` is serialized/deserialized\n get payloadChunks() {\n return btoa(JSON.stringify(changedState)).match(/.{1,2000}/g)\n }\n}\n", "function replaceDocument(content) {\n const head = '<html'\n const tail = '</html'\n const headIndex = content.indexOf(head)\n const tailIndex = content.lastIndexOf(tail)\n if (headIndex >= 0 && tailIndex >= 0) {\n const html = content.slice(content.indexOf('>', headIndex) + 1, tailIndex)\n document.documentElement.innerHTML = html\n }\n}\n\nfunction append(content) {\n document.body.insertAdjacentHTML('beforeend', content)\n}\n\nexport default { append, replaceDocument }\n", "const active = {}\n\nfunction add(payload) {\n active[payload.id] = payload\n}\n\nfunction remove(id) {\n delete active[id]\n}\n\nexport default {\n add,\n remove,\n get commands() {\n return [...Object.values(active)]\n },\n get length() {\n return Object.keys(active).length\n }\n}\n", "import activity from './activity'\nimport { dispatch, commandEvents } from './events'\n\nfunction finish(event) {\n event.detail.endedAt = Date.now()\n event.detail.milliseconds = event.detail.endedAt - event.detail.startedAt\n setTimeout(() => dispatch(commandEvents.finish, event.target, { detail: event.detail }), 25)\n}\n\n// TODO: forward source event to finish (error or success)\naddEventListener(commandEvents.serverError, finish)\naddEventListener(commandEvents.success, finish)\naddEventListener(commandEvents.finish, event => activity.remove(event.detail.id), true)\n\nexport default { events: commandEvents }\n", "import meta from './meta'\nimport state from './state'\nimport renderer from './renderer'\nimport { dispatch } from './events'\nimport lifecycle from './lifecycle'\n\nconst frameSources = {}\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchOptions } = event.detail\n\n // command invoked and busy\n if (meta.busy) {\n let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']]\n acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ')\n fetchOptions.headers['Accept'] = acceptHeaders\n fetchOptions.headers['TurboBoost-Token'] = meta.token\n }\n\n // always send state\n state.payloadChunks.forEach((chunk, i) => {\n fetchOptions.headers[`TurboBoost-State-${i.toString().padStart(4, '0')}`] = chunk\n })\n})\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchResponse: response } = event.detail\n\n if (frame) frameSources[frame.id] = frame.src\n\n if (response.header('TurboBoost')) {\n if (response.statusCode < 200 || response.statusCode > 399) {\n const error = `Server returned a ${response.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error } }, true)\n }\n\n if (response.header('TurboBoost') === 'Append') {\n event.preventDefault()\n response.responseText.then(content => renderer.append(content))\n }\n }\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target.closest('turbo-frame')\n frame.dataset.turboBoostSrc = frameSources[frame.id] || frame.src || frame.dataset.turboBoostSrc\n delete frameSources[frame.id]\n})\n", "const schema = {\n // attributes\n frameAttribute: 'data-turbo-frame',\n methodAttribute: 'data-turbo-method',\n commandAttribute: 'data-turbo-command',\n confirmAttribute: 'data-turbo-confirm'\n}\n\nexport default { ...schema }\n", "import { commandEvents } from './events'\nimport schema from './schema'\n\nconst confirmation = {\n method: message => Promise.resolve(confirm(message))\n}\n\nconst isTurboMethod = event => event.detail.driver === 'method'\n\nconst isTurboForm = event => {\n if (event.detail.driver !== 'form') return false\n\n const element = event.target\n const frame = element.closest('turbo-frame')\n const target = element.closest(`[${schema.frameAttribute}]`)\n return !!(frame || target)\n}\n\nconst shouldDelegate = event => isTurboMethod(event) || isTurboForm(event)\n\ndocument.addEventListener(commandEvents.start, async event => {\n const message = event.target.getAttribute(schema.confirmAttribute)\n if (!message) return\n\n event.detail.confirmation = true\n\n if (shouldDelegate(event)) return // delegate confirmation handling to Turbo\n\n const proceed = await confirmation.method(message)\n if (!proceed) event.preventDefault()\n})\n\nexport default confirmation\n", "let events = []\nlet eventListener\n\nfunction register(eventName, selectors) {\n const match = events.find(evt => evt.name === eventName)\n if (match) events.splice(events.indexOf(match), 1)\n events = [{ name: eventName, selectors }, ...events]\n\n document.removeEventListener(eventName, eventListener, true)\n document.addEventListener(eventName, eventListener, true)\n\n return { ...events.find(evt => evt.name === eventName) }\n}\n\nfunction getRegisteredEventForElement(element) {\n return events.find(evt =>\n evt.selectors.find(selector => Array.from(document.querySelectorAll(selector)).find(el => el === element))\n )\n}\n\nfunction isRegisteredForElement(eventName, element) {\n const evt = getRegisteredEventForElement(element)\n return evt && evt.name === eventName\n}\n\nexport default {\n register,\n isRegisteredForElement,\n get events() {\n return [...events]\n },\n set handler(fn) {\n eventListener = fn\n }\n}\n", "import schema from './schema'\nimport lifecycle from './lifecycle'\n\nfunction findClosestCommand(element) {\n return element.closest(`[${schema.commandAttribute}]`)\n}\n\nfunction findClosestFrameWithSource(element) {\n return (\n element.closest('turbo-frame[src]') ||\n element.closest('turbo-frame[data-turbo-frame-src]') ||\n element.closest('turbo-frame')\n )\n}\n\nfunction assignElementValueToPayload(element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select') return (payload.value = element.value || null)\n\n if (!element.multiple) return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload(element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n let value = attr.value\n memo[attr.name] = value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = !!element.checked\n payload.disabled = !!element.disabled\n assignElementValueToPayload(element, payload)\n\n // reduce payload size to keep URL length smaller\n delete payload.class\n delete payload.action\n delete payload.href\n delete payload[schema.commandAttribute]\n delete payload[schema.frameAttribute]\n\n return payload\n}\n\nexport default {\n buildAttributePayload,\n findClosestCommand,\n findClosestFrameWithSource\n}\n", "import meta from '../meta'\n\nfunction invokeCommand(form, payload = {}, event = {}) {\n payload.token = meta.token\n const input = form.querySelector('input[name=\"turbo_boost_command\"]') || document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_boost_command'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nexport default { invokeCommand }\n", "function build(urlString, payload = {}) {\n const a = document.createElement('a')\n a.href = urlString\n const url = new URL(a)\n url.searchParams.set('turbo_boost_command', JSON.stringify(payload))\n return url\n}\n\nexport default { build }\n", "import urls from '../urls'\n\nfunction invokeCommand(frame, payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n frame.src = urls.build(src, payload)\n}\n\nexport default { invokeCommand }\n", "import urls from '../urls'\n\nfunction invokeCommand(element, payload = {}) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n delete payload.href\n element.setAttribute('href', urls.build(src, payload))\n}\n\nexport default { invokeCommand }\n", "import meta from '../meta'\nimport state from '../state'\nimport { dispatch } from '../events'\nimport lifecycle from '../lifecycle'\nimport urls from '../urls'\nimport renderer from '../renderer'\n\nfunction aborted(event) {\n const xhr = event.target\n dispatch(lifecycle.events.abort, document, {\n detail: { ...event.detail, xhr }\n })\n}\n\nfunction errored(event) {\n const xhr = event.target\n\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n\n if (append) renderer.append(xhr.responseText)\n\n const error = `Server returned a ${xhr.status} status code! TurboBoost Commands require 2XX-3XX status codes.`\n\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error, xhr } }, true)\n}\n\nfunction loaded(event) {\n const xhr = event.target\n if (xhr.status < 200 || xhr.status > 399) return errored(event)\n const content = xhr.responseText\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n append ? renderer.append(xhr.responseText) : renderer.replaceDocument(xhr.responseText)\n}\n\nfunction invokeCommand(payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', urls.build(src, payload), true)\n xhr.setRequestHeader('Accept', 'text/vnd.turbo-boost.html, text/html, application/xhtml+xml')\n xhr.setRequestHeader('TurboBoost-Token', meta.token)\n state.payloadChunks.forEach((chunk, i) =>\n xhr.setRequestHeader(`TurboBoost-State-${i.toString().padStart(4, '0')}`, chunk)\n )\n\n xhr.addEventListener('abort', aborted)\n xhr.addEventListener('error', errored)\n xhr.addEventListener('load', loaded)\n xhr.send()\n } catch (ex) {\n const message = `Unexpected error sending HTTP request! ${ex.message}`\n errored(ex, { detail: { message } })\n }\n}\n\nexport default { invokeCommand }\n", "import elements from '../elements'\nimport formDriver from './form'\nimport frameDriver from './frame'\nimport methodDriver from './method'\nimport windowDriver from './window'\n\nfunction src(element, frame) {\n frame = frame || { dataset: {} }\n return element.href || frame.src || frame.dataset.turboBoostSrc || location.href\n}\n\nfunction find(element) {\n let frame = elements.findClosestFrameWithSource(element)\n\n const { turboFrame, turboMethod } = element.dataset\n\n if (element.tagName.toLowerCase() === 'form')\n return {\n name: 'form',\n reason: 'Element is a form.',\n frame,\n src: element.action,\n invokeCommand: formDriver.invokeCommand\n }\n\n if (turboMethod && turboMethod.length > 0)\n return {\n name: 'method',\n reason: 'Element defines data-turbo-method.',\n frame,\n src: element.href,\n invokeCommand: methodDriver.invokeCommand\n }\n\n // element targets a frame that is not _self\n if (turboFrame && turboFrame !== '_self') {\n frame = document.getElementById(turboFrame)\n return {\n name: 'frame',\n reason: 'element targets a frame that is not _self',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n }\n\n // element does NOT target a frame or targets _self and is contained by a frame\n if ((!turboFrame || turboFrame === '_self') && frame)\n return {\n name: 'frame',\n reason: 'element does NOT target a frame or targets _self and is contained by a frame',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n\n // element matches one or more of the following conditions\n // - targets _top\n // - does NOT target a frame\n // - is NOT contained by a frame\n return {\n name: 'window',\n reason:\n 'element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)',\n frame: null,\n src: src(element),\n invokeCommand: windowDriver.invokeCommand\n }\n}\n\nexport default { find }\n", "import { allEvents as events } from './events'\n\nlet currentLevel = 'unknown'\n\nconst logLevels = {\n debug: Object.values(events),\n info: Object.values(events),\n warn: [events.abort, events.clientError, events.serverError],\n error: [events.clientError, events.serverError],\n unknown: []\n}\n\nObject.values(events).forEach(name => {\n addEventListener(name, event => {\n if (logLevels[currentLevel].includes(event.type)) {\n const { target, detail } = event\n console[currentLevel](event.type, { target, detail })\n }\n })\n})\n\nexport default {\n get level() {\n return currentLevel\n },\n set level(value) {\n if (!Object.keys(logLevels).includes(value)) value = 'unknown'\n return (currentLevel = value)\n }\n}\n", "function v4() {\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\n )\n}\n\nexport default { v4 }\n", "import './turbo'\nimport schema from './schema'\nimport { dispatch, commandEvents, stateEvents } from './events'\nimport activity from './activity'\nimport confirmation from './confirmation'\nimport delegates from './delegates'\nimport drivers from './drivers'\nimport meta from './meta'\nimport elements from './elements'\nimport lifecycle from './lifecycle'\nimport logger from './logger'\nimport state from './state'\nimport urls from './urls'\nimport uuids from './uuids'\n\nfunction buildCommandPayload(id, element) {\n return {\n id, // uniquely identifies the command\n name: element.getAttribute(schema.commandAttribute),\n elementId: element.id.length > 0 ? element.id : null,\n elementAttributes: elements.buildAttributePayload(element),\n startedAt: Date.now()\n }\n}\n\nasync function invokeCommand(event) {\n let element\n let payload = {}\n\n try {\n element = elements.findClosestCommand(event.target)\n if (!element) return\n if (!delegates.isRegisteredForElement(event.type, element)) return\n\n const commandId = `turbo-command-${uuids.v4()}`\n let driver = drivers.find(element)\n let payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n const startEvent = await dispatch(commandEvents.start, element, {\n cancelable: true,\n detail: payload\n })\n\n if (startEvent.defaultPrevented || (startEvent.detail.confirmation && event.defaultPrevented))\n return dispatch(commandEvents.abort, element, {\n detail: {\n message: `An event handler for '${commandEvents.start}' prevented default behavior and blocked command invocation!`,\n source: startEvent\n }\n })\n\n // the element and thus the driver may have changed based on the start event handler(s)\n driver = drivers.find(element)\n payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n activity.add(payload)\n\n if (['frame', 'window'].includes(driver.name)) event.preventDefault()\n\n meta.busy = true\n setTimeout(() => (meta.busy = false), 10)\n\n switch (driver.name) {\n case 'method':\n return driver.invokeCommand(element, payload)\n case 'form':\n return driver.invokeCommand(element, payload, event)\n case 'frame':\n return driver.invokeCommand(driver.frame, payload)\n case 'window':\n return driver.invokeCommand(payload)\n }\n } catch (error) {\n dispatch(commandEvents.clientError, element, {\n detail: { ...payload, error }\n })\n }\n}\n\nself.TurboBoost = self.TurboBoost || {}\n\nself.TurboBoost = {\n ...self.TurboBoost,\n\n stateEvents,\n\n get state() {\n return state.current\n },\n\n get stateDelta() {\n return state.delta\n }\n}\n\nif (!self.TurboBoost.Commands) {\n // wire things up and setup defaults for event delegation\n delegates.handler = invokeCommand\n delegates.register('click', [`[${schema.commandAttribute}]`])\n delegates.register('submit', [`form[${schema.commandAttribute}]`])\n delegates.register('change', [\n `input[${schema.commandAttribute}]`,\n `select[${schema.commandAttribute}]`,\n `textarea[${schema.commandAttribute}]`\n ])\n\n self.TurboBoost.Commands = {\n confirmation,\n logger,\n schema,\n events: commandEvents,\n registerEventDelegate: delegates.register,\n get eventDelegates() {\n return delegates.events\n }\n }\n}\n\nexport default self.TurboBoost.Commands\n"],
5
- "mappings": "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",
6
- "names": ["Meta", "value", "meta_default", "commandEvents", "stateEvents", "allEvents", "__spreadValues", "dispatch", "name", "target", "options", "resolve", "evt", "__spreadProps", "head", "observable", "object", "parent", "proxy", "target", "key", "dispatch", "stateEvents", "meta_default", "value", "receiver", "index", "observable_default", "loadedState", "currentState", "changedState", "loadStateTimeout", "loadState", "meta_default", "loadStateLater", "json", "observable_default", "__spreadValues", "dispatch", "stateEvents", "commandEvents", "event", "key", "value", "state_default", "replaceDocument", "content", "head", "tail", "headIndex", "tailIndex", "html", "append", "renderer_default", "active", "add", "payload", "remove", "id", "activity_default", "finish", "event", "dispatch", "commandEvents", "activity_default", "lifecycle_default", "frameSources", "event", "frame", "fetchOptions", "meta_default", "acceptHeaders", "entry", "state_default", "chunk", "i", "response", "error", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "content", "renderer_default", "schema", "schema_default", "__spreadValues", "confirmation", "message", "isTurboMethod", "event", "isTurboForm", "element", "frame", "target", "schema_default", "shouldDelegate", "commandEvents", "confirmation_default", "events", "eventListener", "register", "eventName", "selectors", "match", "evt", "__spreadValues", "getRegisteredEventForElement", "element", "selector", "el", "isRegisteredForElement", "delegates_default", "fn", "findClosestCommand", "element", "schema_default", "findClosestFrameWithSource", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "value", "elements_default", "invokeCommand", "form", "payload", "event", "meta_default", "input", "form_default", "build", "urlString", "payload", "a", "url", "urls_default", "invokeCommand", "frame", "payload", "src", "__spreadValues", "urls_default", "frame_default", "invokeCommand", "element", "payload", "src", "__spreadValues", "urls_default", "method_default", "aborted", "event", "xhr", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "errored", "renderer_default", "error", "loaded", "content", "invokeCommand", "payload", "src", "urls_default", "meta_default", "state_default", "chunk", "i", "ex", "message", "window_default", "src", "element", "frame", "find", "elements_default", "turboFrame", "turboMethod", "form_default", "method_default", "frame_default", "window_default", "drivers_default", "currentLevel", "logLevels", "allEvents", "name", "event", "target", "detail", "logger_default", "value", "v4", "c", "uuids_default", "buildCommandPayload", "id", "element", "schema_default", "elements_default", "invokeCommand", "event", "payload", "delegates_default", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "commandEvents", "activity_default", "meta_default", "error", "stateEvents", "state_default", "confirmation_default", "logger_default", "javascript_default"]
3
+ "sources": ["../../../javascript/events.js", "../../../javascript/state/observable.js", "../../../javascript/state/index.js", "../../../javascript/renderer.js", "../../../javascript/activity.js", "../../../javascript/lifecycle.js", "../../../javascript/turbo.js", "../../../javascript/schema.js", "../../../javascript/confirmation.js", "../../../javascript/delegates.js", "../../../javascript/elements.js", "../../../javascript/drivers/form.js", "../../../javascript/urls.js", "../../../javascript/drivers/frame.js", "../../../javascript/drivers/method.js", "../../../javascript/drivers/window.js", "../../../javascript/drivers/index.js", "../../../javascript/logger.js", "../../../javascript/uuids.js", "../../../javascript/index.js"],
4
+ "sourcesContent": ["export const commandEvents = {\n start: 'turbo-boost:command:start',\n success: 'turbo-boost:command:success',\n finish: 'turbo-boost:command:finish',\n abort: 'turbo-boost:command:abort',\n clientError: 'turbo-boost:command:client-error',\n serverError: 'turbo-boost:command:server-error'\n}\n\nexport const stateEvents = {\n stateLoad: 'turbo-boost:state:load',\n stateChange: 'turbo-boost:state:change'\n}\n\nexport const allEvents = { ...commandEvents, ...stateEvents }\n\nexport function dispatch(name, target, options = {}) {\n return new Promise(resolve => {\n options = options || {}\n options.detail = options.detail || {}\n target = target || document\n const evt = new CustomEvent(name, { ...options, bubbles: true })\n target.dispatchEvent(evt)\n resolve(evt)\n })\n}\n", "import { dispatch, stateEvents as events } from '../events'\n\nlet head\n\nfunction observable(object, parent = null) {\n if (!object || typeof object !== 'object') return object\n\n const proxy = new Proxy(object, {\n deleteProperty(target, key) {\n delete target[key]\n dispatch(events.stateChange, document, { detail: { state: head } })\n return true\n },\n\n set(target, key, value, receiver) {\n target[key] = observable(value, this)\n dispatch(events.stateChange, document, { detail: { state: head } })\n return true\n }\n })\n\n if (Array.isArray(object)) {\n object.forEach((value, index) => (object[index] = observable(value, proxy)))\n } else if (typeof object === 'object') {\n for (const [key, value] of Object.entries(object)) object[key] = observable(value, proxy)\n }\n\n if (!parent) head = proxy\n return proxy\n}\n\nexport default observable\n", "// TODO: Consider moving State to its own library\nimport observable from './observable'\nimport { dispatch, commandEvents, stateEvents } from '../events'\n\nlet initialState, currentState, changedState, signedState\n\nfunction initialize(initial, signed) {\n const json = JSON.parse(initial)\n initialState = { ...json }\n signedState = signed\n currentState = observable(json)\n changedState = {}\n setTimeout(() =>\n dispatch(stateEvents.stateLoad, document, {\n detail: { state: currentState }\n })\n )\n}\n\naddEventListener(stateEvents.stateChange, event => {\n for (const [key, value] of Object.entries(currentState))\n if (initialState[key] !== value) changedState[key] = value\n})\n\nexport default {\n initialize,\n events: stateEvents,\n\n get initial() {\n return initialState\n },\n\n get current() {\n return currentState\n },\n\n get changed() {\n return changedState\n },\n\n get signed() {\n return signedState\n }\n}\n", "function replaceDocument(content) {\n const head = '<html'\n const tail = '</html'\n const headIndex = content.indexOf(head)\n const tailIndex = content.lastIndexOf(tail)\n if (headIndex >= 0 && tailIndex >= 0) {\n const html = content.slice(content.indexOf('>', headIndex) + 1, tailIndex)\n document.documentElement.innerHTML = html\n }\n}\n\nfunction append(content) {\n document.body.insertAdjacentHTML('beforeend', content)\n}\n\nexport default { append, replaceDocument }\n", "const active = {}\n\nfunction add(payload) {\n active[payload.id] = payload\n}\n\nfunction remove(id) {\n delete active[id]\n}\n\nexport default {\n add,\n remove,\n get commands() {\n return [...Object.values(active)]\n },\n get length() {\n return Object.keys(active).length\n }\n}\n", "import activity from './activity'\nimport { dispatch, commandEvents } from './events'\n\nfunction finish(event) {\n event.detail.endedAt = Date.now()\n event.detail.milliseconds = event.detail.endedAt - event.detail.startedAt\n setTimeout(() => dispatch(commandEvents.finish, event.target, { detail: event.detail }), 25)\n}\n\n// TODO: forward source event to finish (error or success)\naddEventListener(commandEvents.serverError, finish)\naddEventListener(commandEvents.success, finish)\naddEventListener(commandEvents.finish, event => activity.remove(event.detail.id), true)\n\nexport default { events: commandEvents }\n", "import state from './state'\nimport renderer from './renderer'\nimport { dispatch } from './events'\nimport lifecycle from './lifecycle'\n\nconst frameSources = {}\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchOptions } = event.detail\n\n // command invoked and busy\n if (self.TurboBoost?.Commands?.busy) {\n let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']]\n acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ')\n fetchOptions.headers['Accept'] = acceptHeaders\n }\n})\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target.closest('turbo-frame')\n const { fetchResponse: response } = event.detail\n\n if (frame) frameSources[frame.id] = frame.src\n\n if (response.header('TurboBoost')) {\n if (response.statusCode < 200 || response.statusCode > 399) {\n const error = `Server returned a ${response.statusCode} status code! TurboBoost Commands require 2XX-3XX status codes.`\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error } }, true)\n }\n\n if (response.header('TurboBoost') === 'Append') {\n event.preventDefault()\n response.responseText.then(content => renderer.append(content))\n }\n }\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target.closest('turbo-frame')\n frame.dataset.turboBoostSrc = frameSources[frame.id] || frame.src || frame.dataset.turboBoostSrc\n delete frameSources[frame.id]\n})\n", "const schema = {\n // attributes\n frameAttribute: 'data-turbo-frame',\n methodAttribute: 'data-turbo-method',\n commandAttribute: 'data-turbo-command',\n confirmAttribute: 'data-turbo-confirm'\n}\n\nexport default { ...schema }\n", "import { commandEvents } from './events'\nimport schema from './schema'\n\nconst confirmation = {\n method: message => Promise.resolve(confirm(message))\n}\n\nconst isTurboMethod = event => event.detail.driver === 'method'\n\nconst isTurboForm = event => {\n if (event.detail.driver !== 'form') return false\n\n const element = event.target\n const frame = element.closest('turbo-frame')\n const target = element.closest(`[${schema.frameAttribute}]`)\n return !!(frame || target)\n}\n\nconst shouldDelegate = event => isTurboMethod(event) || isTurboForm(event)\n\ndocument.addEventListener(commandEvents.start, async event => {\n const message = event.target.getAttribute(schema.confirmAttribute)\n if (!message) return\n\n event.detail.confirmation = true\n\n if (shouldDelegate(event)) return // delegate confirmation handling to Turbo\n\n const proceed = await confirmation.method(message)\n if (!proceed) event.preventDefault()\n})\n\nexport default confirmation\n", "let events = []\nlet eventListener\n\nfunction register(eventName, selectors) {\n const match = events.find(evt => evt.name === eventName)\n if (match) events.splice(events.indexOf(match), 1)\n events = [{ name: eventName, selectors }, ...events]\n\n document.removeEventListener(eventName, eventListener, true)\n document.addEventListener(eventName, eventListener, true)\n\n return { ...events.find(evt => evt.name === eventName) }\n}\n\nfunction getRegisteredEventForElement(element) {\n return events.find(evt =>\n evt.selectors.find(selector => Array.from(document.querySelectorAll(selector)).find(el => el === element))\n )\n}\n\nfunction isRegisteredForElement(eventName, element) {\n const evt = getRegisteredEventForElement(element)\n return evt && evt.name === eventName\n}\n\nexport default {\n register,\n isRegisteredForElement,\n get events() {\n return [...events]\n },\n set handler(fn) {\n eventListener = fn\n }\n}\n", "import schema from './schema'\nimport lifecycle from './lifecycle'\n\nfunction findClosestCommand(element) {\n return element.closest(`[${schema.commandAttribute}]`)\n}\n\nfunction findClosestFrameWithSource(element) {\n return (\n element.closest('turbo-frame[src]') ||\n element.closest('turbo-frame[data-turbo-frame-src]') ||\n element.closest('turbo-frame')\n )\n}\n\nfunction assignElementValueToPayload(element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select') return (payload.value = element.value || null)\n\n if (!element.multiple) return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload(element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n let value = attr.value\n memo[attr.name] = value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = !!element.checked\n payload.disabled = !!element.disabled\n assignElementValueToPayload(element, payload)\n\n // reduce payload size to keep URL length smaller\n delete payload.class\n delete payload.action\n delete payload.href\n delete payload[schema.commandAttribute]\n delete payload[schema.frameAttribute]\n\n return payload\n}\n\nexport default {\n buildAttributePayload,\n findClosestCommand,\n findClosestFrameWithSource\n}\n", "function invokeCommand(form, payload = {}, event = {}) {\n const input = form.querySelector('input[name=\"turbo_boost_command\"]') || document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_boost_command'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nexport default { invokeCommand }\n", "function build(urlString, payload = {}) {\n const a = document.createElement('a')\n a.href = urlString\n const url = new URL(a)\n url.searchParams.set('tbc', JSON.stringify(payload))\n return url\n}\n\nexport default { build }\n", "import urls from '../urls'\n\nfunction invokeCommand(frame, payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n frame.src = urls.build(src, payload)\n}\n\nexport default { invokeCommand }\n", "import urls from '../urls'\n\nfunction invokeCommand(element, payload = {}) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n delete payload.href\n element.setAttribute('href', urls.build(src, payload))\n}\n\nexport default { invokeCommand }\n", "import state from '../state'\nimport { dispatch } from '../events'\nimport lifecycle from '../lifecycle'\nimport urls from '../urls'\nimport renderer from '../renderer'\n\nfunction aborted(event) {\n const xhr = event.target\n dispatch(lifecycle.events.abort, document, {\n detail: { ...event.detail, xhr }\n })\n}\n\nfunction errored(event) {\n const xhr = event.target\n\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n\n if (append) renderer.append(xhr.responseText)\n\n const error = `Server returned a ${xhr.status} status code! TurboBoost Commands require 2XX-3XX status codes.`\n\n dispatch(lifecycle.events.clientError, document, { detail: { ...event.detail, error, xhr } }, true)\n}\n\nfunction loaded(event) {\n const xhr = event.target\n if (xhr.status < 200 || xhr.status > 399) return errored(event)\n const content = xhr.responseText\n const append =\n xhr.getResponseHeader('TurboBoost') === 'Append' ||\n xhr.getResponseHeader('Content-Type').startsWith('text/vnd.turbo-boost.html')\n append ? renderer.append(xhr.responseText) : renderer.replaceDocument(xhr.responseText)\n}\n\nfunction invokeCommand(payload) {\n const src = payload.src\n payload = { ...payload }\n delete payload.src\n\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', urls.build(src, payload), true)\n xhr.setRequestHeader('Accept', 'text/vnd.turbo-boost.html, text/html, application/xhtml+xml')\n xhr.addEventListener('abort', aborted)\n xhr.addEventListener('error', errored)\n xhr.addEventListener('load', loaded)\n xhr.send()\n } catch (ex) {\n const message = `Unexpected error sending HTTP request! ${ex.message}`\n errored(ex, { detail: { message } })\n }\n}\n\nexport default { invokeCommand }\n", "import elements from '../elements'\nimport formDriver from './form'\nimport frameDriver from './frame'\nimport methodDriver from './method'\nimport windowDriver from './window'\n\nfunction src(element, frame) {\n frame = frame || { dataset: {} }\n return element.href || frame.src || frame.dataset.turboBoostSrc || location.href\n}\n\nfunction find(element) {\n let frame = elements.findClosestFrameWithSource(element)\n\n const { turboFrame, turboMethod } = element.dataset\n\n if (element.tagName.toLowerCase() === 'form')\n return {\n name: 'form',\n reason: 'Element is a form.',\n frame,\n src: element.action,\n invokeCommand: formDriver.invokeCommand\n }\n\n if (turboMethod && turboMethod.length > 0)\n return {\n name: 'method',\n reason: 'Element defines data-turbo-method.',\n frame,\n src: element.href,\n invokeCommand: methodDriver.invokeCommand\n }\n\n // element targets a frame that is not _self\n if (turboFrame && turboFrame !== '_self') {\n frame = document.getElementById(turboFrame)\n return {\n name: 'frame',\n reason: 'element targets a frame that is not _self',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n }\n\n // element does NOT target a frame or targets _self and is contained by a frame\n if ((!turboFrame || turboFrame === '_self') && frame)\n return {\n name: 'frame',\n reason: 'element does NOT target a frame or targets _self and is contained by a frame',\n frame,\n src: src(element, frame),\n invokeCommand: frameDriver.invokeCommand\n }\n\n // element matches one or more of the following conditions\n // - targets _top\n // - does NOT target a frame\n // - is NOT contained by a frame\n return {\n name: 'window',\n reason:\n 'element matches one or more of the following conditions (targets _top, does NOT target a frame, is NOT contained by a frame)',\n frame: null,\n src: src(element),\n invokeCommand: windowDriver.invokeCommand\n }\n}\n\nexport default { find }\n", "import { allEvents as events } from './events'\n\nlet currentLevel = 'unknown'\n\nconst logLevels = {\n debug: Object.values(events),\n info: Object.values(events),\n warn: [events.abort, events.clientError, events.serverError],\n error: [events.clientError, events.serverError],\n unknown: []\n}\n\nObject.values(events).forEach(name => {\n addEventListener(name, event => {\n if (logLevels[currentLevel].includes(event.type)) {\n const { target, detail } = event\n console[currentLevel](event.type, { target, detail })\n }\n })\n})\n\nexport default {\n get level() {\n return currentLevel\n },\n set level(value) {\n if (!Object.keys(logLevels).includes(value)) value = 'unknown'\n return (currentLevel = value)\n }\n}\n", "function v4() {\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\n )\n}\n\nexport default { v4 }\n", "import './turbo'\nimport schema from './schema'\nimport { dispatch, commandEvents } from './events'\nimport activity from './activity'\nimport confirmation from './confirmation'\nimport delegates from './delegates'\nimport drivers from './drivers'\nimport elements from './elements'\nimport lifecycle from './lifecycle'\nimport logger from './logger'\nimport state from './state'\nimport urls from './urls'\nimport uuids from './uuids'\n\nconst TurboBoost = self.TurboBoost || {}\n\nconst Commands = {\n busy: false,\n confirmation,\n logger,\n schema,\n events: commandEvents,\n registerEventDelegate: delegates.register,\n get eventDelegates() {\n return delegates.events\n }\n}\n\nfunction buildCommandPayload(id, element) {\n return {\n id, // uniquely identifies the command\n name: element.getAttribute(schema.commandAttribute),\n elementId: element.id.length > 0 ? element.id : null,\n elementAttributes: elements.buildAttributePayload(element),\n startedAt: Date.now(),\n token: Commands.token, // command token (used for CSRF protection)\n signedState: state.signed, // server side state\n clientState: state.changed // client side state (delta of optimistic updates)\n }\n}\n\nasync function invokeCommand(event) {\n let element\n let payload = {}\n\n try {\n element = elements.findClosestCommand(event.target)\n if (!element) return\n if (!delegates.isRegisteredForElement(event.type, element)) return\n\n const commandId = `turbo-command-${uuids.v4()}`\n let driver = drivers.find(element)\n let payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n const startEvent = await dispatch(commandEvents.start, element, {\n cancelable: true,\n detail: payload\n })\n\n if (startEvent.defaultPrevented || (startEvent.detail.confirmation && event.defaultPrevented))\n return dispatch(commandEvents.abort, element, {\n detail: {\n message: `An event handler for '${commandEvents.start}' prevented default behavior and blocked command invocation!`,\n source: startEvent\n }\n })\n\n // the element and thus the driver may have changed based on the start event handler(s)\n driver = drivers.find(element)\n payload = {\n ...buildCommandPayload(commandId, element),\n driver: driver.name,\n frameId: driver.frame ? driver.frame.id : null,\n src: driver.src\n }\n\n activity.add(payload)\n\n if (['frame', 'window'].includes(driver.name)) event.preventDefault()\n\n Commands.busy = true\n setTimeout(() => (Commands.busy = false), 10)\n\n switch (driver.name) {\n case 'method':\n return driver.invokeCommand(element, payload)\n case 'form':\n return driver.invokeCommand(element, payload, event)\n case 'frame':\n return driver.invokeCommand(driver.frame, payload)\n case 'window':\n return driver.invokeCommand(payload)\n }\n } catch (error) {\n dispatch(commandEvents.clientError, element, {\n detail: { ...payload, error }\n })\n }\n}\n\nself.TurboBoost = { ...TurboBoost }\n\nif (!self.TurboBoost.Commands) {\n // wire things up and setup defaults for event delegation\n delegates.handler = invokeCommand\n delegates.register('click', [`[${schema.commandAttribute}]`])\n delegates.register('submit', [`form[${schema.commandAttribute}]`])\n delegates.register('change', [\n `input[${schema.commandAttribute}]`,\n `select[${schema.commandAttribute}]`,\n `textarea[${schema.commandAttribute}]`\n ])\n\n self.TurboBoost.Commands = Commands\n self.TurboBoost.State = state\n}\n\nexport default Commands\n"],
5
+ "mappings": "+aAAO,IAAMA,EAAgB,CAC3B,MAAO,4BACP,QAAS,8BACT,OAAQ,6BACR,MAAO,4BACP,YAAa,mCACb,YAAa,kCACf,EAEaC,EAAc,CACzB,UAAW,yBACX,YAAa,0BACf,EAEaC,EAAYC,IAAA,GAAKH,GAAkBC,GAEzC,SAASG,EAASC,EAAMC,EAAQC,EAAU,CAAC,EAAG,CACnD,OAAO,IAAI,QAAQC,GAAW,CAC5BD,EAAUA,GAAW,CAAC,EACtBA,EAAQ,OAASA,EAAQ,QAAU,CAAC,EACpCD,EAASA,GAAU,SACnB,IAAMG,EAAM,IAAI,YAAYJ,EAAMK,EAAAP,EAAA,GAAKI,GAAL,CAAc,QAAS,EAAK,EAAC,EAC/DD,EAAO,cAAcG,CAAG,EACxBD,EAAQC,CAAG,CACb,CAAC,CACH,CCvBA,IAAIE,EAEJ,SAASC,EAAWC,EAAQC,EAAS,KAAM,CACzC,GAAI,CAACD,GAAU,OAAOA,GAAW,SAAU,OAAOA,EAElD,IAAME,EAAQ,IAAI,MAAMF,EAAQ,CAC9B,eAAeG,EAAQC,EAAK,CAC1B,cAAOD,EAAOC,CAAG,EACjBC,EAASC,EAAO,YAAa,SAAU,CAAE,OAAQ,CAAE,MAAOR,CAAK,CAAE,CAAC,EAC3D,EACT,EAEA,IAAIK,EAAQC,EAAKG,EAAOC,EAAU,CAChC,OAAAL,EAAOC,CAAG,EAAIL,EAAWQ,EAAO,IAAI,EACpCF,EAASC,EAAO,YAAa,SAAU,CAAE,OAAQ,CAAE,MAAOR,CAAK,CAAE,CAAC,EAC3D,EACT,CACF,CAAC,EAED,GAAI,MAAM,QAAQE,CAAM,EACtBA,EAAO,QAAQ,CAACO,EAAOE,IAAWT,EAAOS,CAAK,EAAIV,EAAWQ,EAAOL,CAAK,CAAE,UAClE,OAAOF,GAAW,SAC3B,OAAW,CAACI,EAAKG,CAAK,IAAK,OAAO,QAAQP,CAAM,EAAGA,EAAOI,CAAG,EAAIL,EAAWQ,EAAOL,CAAK,EAG1F,OAAKD,IAAQH,EAAOI,GACbA,CACT,CAEA,IAAOQ,EAAQX,EC3Bf,IAAIY,EAAcC,EAAcC,EAAcC,EAE9C,SAASC,GAAWC,EAASC,EAAQ,CACnC,IAAMC,EAAO,KAAK,MAAMF,CAAO,EAC/BL,EAAeQ,EAAA,GAAKD,GACpBJ,EAAcG,EACdL,EAAeQ,EAAWF,CAAI,EAC9BL,EAAe,CAAC,EAChB,WAAW,IACTQ,EAASC,EAAY,UAAW,SAAU,CACxC,OAAQ,CAAE,MAAOV,CAAa,CAChC,CAAC,CACH,CACF,CAEA,iBAAiBU,EAAY,YAAaC,GAAS,CACjD,OAAW,CAACC,EAAKC,CAAK,IAAK,OAAO,QAAQb,CAAY,EAChDD,EAAaa,CAAG,IAAMC,IAAOZ,EAAaW,CAAG,EAAIC,EACzD,CAAC,EAED,IAAOC,EAAQ,CACb,WAAAX,GACA,OAAQO,EAER,IAAI,SAAU,CACZ,OAAOX,CACT,EAEA,IAAI,SAAU,CACZ,OAAOC,CACT,EAEA,IAAI,SAAU,CACZ,OAAOC,CACT,EAEA,IAAI,QAAS,CACX,OAAOC,CACT,CACF,EC3CA,SAASa,GAAgBC,EAAS,CAChC,IAAMC,EAAO,QACPC,EAAO,SACPC,EAAYH,EAAQ,QAAQC,CAAI,EAChCG,EAAYJ,EAAQ,YAAYE,CAAI,EAC1C,GAAIC,GAAa,GAAKC,GAAa,EAAG,CACpC,IAAMC,EAAOL,EAAQ,MAAMA,EAAQ,QAAQ,IAAKG,CAAS,EAAI,EAAGC,CAAS,EACzE,SAAS,gBAAgB,UAAYC,CACvC,CACF,CAEA,SAASC,GAAON,EAAS,CACvB,SAAS,KAAK,mBAAmB,YAAaA,CAAO,CACvD,CAEA,IAAOO,EAAQ,CAAE,OAAAD,GAAQ,gBAAAP,EAAgB,ECfzC,IAAMS,EAAS,CAAC,EAEhB,SAASC,GAAIC,EAAS,CACpBF,EAAOE,EAAQ,EAAE,EAAIA,CACvB,CAEA,SAASC,GAAOC,EAAI,CAClB,OAAOJ,EAAOI,CAAE,CAClB,CAEA,IAAOC,EAAQ,CACb,IAAAJ,GACA,OAAAE,GACA,IAAI,UAAW,CACb,MAAO,CAAC,GAAG,OAAO,OAAOH,CAAM,CAAC,CAClC,EACA,IAAI,QAAS,CACX,OAAO,OAAO,KAAKA,CAAM,EAAE,MAC7B,CACF,EChBA,SAASM,EAAOC,EAAO,CACrBA,EAAM,OAAO,QAAU,KAAK,IAAI,EAChCA,EAAM,OAAO,aAAeA,EAAM,OAAO,QAAUA,EAAM,OAAO,UAChE,WAAW,IAAMC,EAASC,EAAc,OAAQF,EAAM,OAAQ,CAAE,OAAQA,EAAM,MAAO,CAAC,EAAG,EAAE,CAC7F,CAGA,iBAAiBE,EAAc,YAAaH,CAAM,EAClD,iBAAiBG,EAAc,QAASH,CAAM,EAC9C,iBAAiBG,EAAc,OAAQF,GAASG,EAAS,OAAOH,EAAM,OAAO,EAAE,EAAG,EAAI,EAEtF,IAAOI,EAAQ,CAAE,OAAQF,CAAc,ECTvC,IAAMG,EAAe,CAAC,EAGtB,iBAAiB,6BAA8BC,GAAS,CARxD,IAAAC,EAAAC,EASE,IAAMC,EAAQH,EAAM,OAAO,QAAQ,aAAa,EAC1C,CAAE,aAAAI,CAAa,EAAIJ,EAAM,OAG/B,IAAIE,GAAAD,EAAA,KAAK,aAAL,YAAAA,EAAiB,WAAjB,MAAAC,EAA2B,KAAM,CACnC,IAAIG,EAAgB,CAAC,4BAA6BD,EAAa,QAAQ,MAAS,EAChFC,EAAgBA,EAAc,OAAOC,GAASA,GAASA,EAAM,KAAK,EAAE,OAAS,CAAC,EAAE,KAAK,IAAI,EACzFF,EAAa,QAAQ,OAAYC,CACnC,CACF,CAAC,EAGD,iBAAiB,8BAA+BL,GAAS,CACvD,IAAMG,EAAQH,EAAM,OAAO,QAAQ,aAAa,EAC1C,CAAE,cAAeO,CAAS,EAAIP,EAAM,OAI1C,GAFIG,IAAOJ,EAAaI,EAAM,EAAE,EAAIA,EAAM,KAEtCI,EAAS,OAAO,YAAY,EAAG,CACjC,GAAIA,EAAS,WAAa,KAAOA,EAAS,WAAa,IAAK,CAC1D,IAAMC,EAAQ,qBAAqBD,EAAS,UAAU,kEACtDE,EAASC,EAAU,OAAO,YAAa,SAAU,CAAE,OAAQC,EAAAC,EAAA,GAAKZ,EAAM,QAAX,CAAmB,MAAAQ,CAAM,EAAE,EAAG,EAAI,CAC/F,CAEID,EAAS,OAAO,YAAY,IAAM,WACpCP,EAAM,eAAe,EACrBO,EAAS,aAAa,KAAKM,GAAWC,EAAS,OAAOD,CAAO,CAAC,EAElE,CACF,CAAC,EAGD,iBAAiB,mBAAoBb,GAAS,CAC5C,IAAMG,EAAQH,EAAM,OAAO,QAAQ,aAAa,EAChDG,EAAM,QAAQ,cAAgBJ,EAAaI,EAAM,EAAE,GAAKA,EAAM,KAAOA,EAAM,QAAQ,cACnF,OAAOJ,EAAaI,EAAM,EAAE,CAC9B,CAAC,EC7CD,IAAMY,GAAS,CAEb,eAAgB,mBAChB,gBAAiB,oBACjB,iBAAkB,qBAClB,iBAAkB,oBACpB,EAEOC,EAAQC,EAAA,GAAKF,ICLpB,IAAMG,EAAe,CACnB,OAAQC,GAAW,QAAQ,QAAQ,QAAQA,CAAO,CAAC,CACrD,EAEMC,GAAgBC,GAASA,EAAM,OAAO,SAAW,SAEjDC,GAAcD,GAAS,CAC3B,GAAIA,EAAM,OAAO,SAAW,OAAQ,MAAO,GAE3C,IAAME,EAAUF,EAAM,OAChBG,EAAQD,EAAQ,QAAQ,aAAa,EACrCE,EAASF,EAAQ,QAAQ,IAAIG,EAAO,cAAc,GAAG,EAC3D,MAAO,CAAC,EAAEF,GAASC,EACrB,EAEME,GAAiBN,GAASD,GAAcC,CAAK,GAAKC,GAAYD,CAAK,EAEzE,SAAS,iBAAiBO,EAAc,MAAO,MAAMP,GAAS,CAC5D,IAAMF,EAAUE,EAAM,OAAO,aAAaK,EAAO,gBAAgB,EAKjE,GAJI,CAACP,IAELE,EAAM,OAAO,aAAe,GAExBM,GAAeN,CAAK,GAAG,OAEX,MAAMH,EAAa,OAAOC,CAAO,GACnCE,EAAM,eAAe,CACrC,CAAC,EAED,IAAOQ,EAAQX,EChCf,IAAIY,EAAS,CAAC,EACVC,EAEJ,SAASC,GAASC,EAAWC,EAAW,CACtC,IAAMC,EAAQL,EAAO,KAAKM,GAAOA,EAAI,OAASH,CAAS,EACvD,OAAIE,GAAOL,EAAO,OAAOA,EAAO,QAAQK,CAAK,EAAG,CAAC,EACjDL,EAAS,CAAC,CAAE,KAAMG,EAAW,UAAAC,CAAU,EAAG,GAAGJ,CAAM,EAEnD,SAAS,oBAAoBG,EAAWF,EAAe,EAAI,EAC3D,SAAS,iBAAiBE,EAAWF,EAAe,EAAI,EAEjDM,EAAA,GAAKP,EAAO,KAAKM,GAAOA,EAAI,OAASH,CAAS,EACvD,CAEA,SAASK,GAA6BC,EAAS,CAC7C,OAAOT,EAAO,KAAKM,GACjBA,EAAI,UAAU,KAAKI,GAAY,MAAM,KAAK,SAAS,iBAAiBA,CAAQ,CAAC,EAAE,KAAKC,GAAMA,IAAOF,CAAO,CAAC,CAC3G,CACF,CAEA,SAASG,GAAuBT,EAAWM,EAAS,CAClD,IAAMH,EAAME,GAA6BC,CAAO,EAChD,OAAOH,GAAOA,EAAI,OAASH,CAC7B,CAEA,IAAOU,EAAQ,CACb,SAAAX,GACA,uBAAAU,GACA,IAAI,QAAS,CACX,MAAO,CAAC,GAAGZ,CAAM,CACnB,EACA,IAAI,QAAQc,EAAI,CACdb,EAAgBa,CAClB,CACF,EC/BA,SAASC,GAAmBC,EAAS,CACnC,OAAOA,EAAQ,QAAQ,IAAIC,EAAO,gBAAgB,GAAG,CACvD,CAEA,SAASC,GAA2BF,EAAS,CAC3C,OACEA,EAAQ,QAAQ,kBAAkB,GAClCA,EAAQ,QAAQ,mCAAmC,GACnDA,EAAQ,QAAQ,aAAa,CAEjC,CAEA,SAASG,GAA4BH,EAASI,EAAU,CAAC,EAAG,CAC1D,GAAIJ,EAAQ,QAAQ,YAAY,IAAM,SAAU,OAAQI,EAAQ,MAAQJ,EAAQ,OAAS,KAEzF,GAAI,CAACA,EAAQ,SAAU,OAAQI,EAAQ,MAAQJ,EAAQ,QAAQA,EAAQ,aAAa,EAAE,MAEtFI,EAAQ,OAAS,MAAM,KAAKJ,EAAQ,OAAO,EAAE,OAAO,CAACK,EAAMC,KACrDA,EAAO,UAAUD,EAAK,KAAKC,EAAO,KAAK,EACpCD,GACN,CAAC,CAAC,CACP,CAEA,SAASE,GAAsBP,EAAS,CACtC,IAAMI,EAAU,MAAM,KAAKJ,EAAQ,UAAU,EAAE,OAAO,CAACK,EAAMG,IAAS,CACpE,IAAIC,EAAQD,EAAK,MACjB,OAAAH,EAAKG,EAAK,IAAI,EAAIC,EACXJ,CACT,EAAG,CAAC,CAAC,EAEL,OAAAD,EAAQ,IAAMJ,EAAQ,QACtBI,EAAQ,QAAU,CAAC,CAACJ,EAAQ,QAC5BI,EAAQ,SAAW,CAAC,CAACJ,EAAQ,SAC7BG,GAA4BH,EAASI,CAAO,EAG5C,OAAOA,EAAQ,MACf,OAAOA,EAAQ,OACf,OAAOA,EAAQ,KACf,OAAOA,EAAQH,EAAO,gBAAgB,EACtC,OAAOG,EAAQH,EAAO,cAAc,EAE7BG,CACT,CAEA,IAAOM,EAAQ,CACb,sBAAAH,GACA,mBAAAR,GACA,2BAAAG,EACF,ECpDA,SAASS,GAAcC,EAAMC,EAAU,CAAC,EAAGC,EAAQ,CAAC,EAAG,CACrD,IAAMC,EAAQH,EAAK,cAAc,mCAAmC,GAAK,SAAS,cAAc,OAAO,EACvGG,EAAM,KAAO,SACbA,EAAM,KAAO,sBACbA,EAAM,MAAQ,KAAK,UAAUF,CAAO,EACpCD,EAAK,YAAYG,CAAK,CACxB,CAEA,IAAOC,EAAQ,CAAE,cAAAL,EAAc,ECR/B,SAASM,GAAMC,EAAWC,EAAU,CAAC,EAAG,CACtC,IAAMC,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAOF,EACT,IAAMG,EAAM,IAAI,IAAID,CAAC,EACrB,OAAAC,EAAI,aAAa,IAAI,MAAO,KAAK,UAAUF,CAAO,CAAC,EAC5CE,CACT,CAEA,IAAOC,EAAQ,CAAE,MAAAL,EAAM,ECNvB,SAASM,GAAcC,EAAOC,EAAS,CACrC,IAAMC,EAAMD,EAAQ,IACpBA,EAAUE,EAAA,GAAKF,GACf,OAAOA,EAAQ,IACfD,EAAM,IAAMI,EAAK,MAAMF,EAAKD,CAAO,CACrC,CAEA,IAAOI,EAAQ,CAAE,cAAAN,EAAc,ECP/B,SAASO,GAAcC,EAASC,EAAU,CAAC,EAAG,CAC5C,IAAMC,EAAMD,EAAQ,IACpBA,EAAUE,EAAA,GAAKF,GACf,OAAOA,EAAQ,IACf,OAAOA,EAAQ,KACfD,EAAQ,aAAa,OAAQI,EAAK,MAAMF,EAAKD,CAAO,CAAC,CACvD,CAEA,IAAOI,EAAQ,CAAE,cAAAN,EAAc,ECJ/B,SAASO,GAAQC,EAAO,CACtB,IAAMC,EAAMD,EAAM,OAClBE,EAASC,EAAU,OAAO,MAAO,SAAU,CACzC,OAAQC,EAAAC,EAAA,GAAKL,EAAM,QAAX,CAAmB,IAAAC,CAAI,EACjC,CAAC,CACH,CAEA,SAASK,EAAQN,EAAO,CACtB,IAAMC,EAAMD,EAAM,QAGhBC,EAAI,kBAAkB,YAAY,IAAM,UACxCA,EAAI,kBAAkB,cAAc,EAAE,WAAW,2BAA2B,IAElEM,EAAS,OAAON,EAAI,YAAY,EAE5C,IAAMO,EAAQ,qBAAqBP,EAAI,MAAM,kEAE7CC,EAASC,EAAU,OAAO,YAAa,SAAU,CAAE,OAAQC,EAAAC,EAAA,GAAKL,EAAM,QAAX,CAAmB,MAAAQ,EAAO,IAAAP,CAAI,EAAE,EAAG,EAAI,CACpG,CAEA,SAASQ,GAAOT,EAAO,CACrB,IAAMC,EAAMD,EAAM,OAClB,GAAIC,EAAI,OAAS,KAAOA,EAAI,OAAS,IAAK,OAAOK,EAAQN,CAAK,EAC9D,IAAMU,EAAUT,EAAI,aAElBA,EAAI,kBAAkB,YAAY,IAAM,UACxCA,EAAI,kBAAkB,cAAc,EAAE,WAAW,2BAA2B,EACrEM,EAAS,OAAON,EAAI,YAAY,EAAIM,EAAS,gBAAgBN,EAAI,YAAY,CACxF,CAEA,SAASU,GAAcC,EAAS,CAC9B,IAAMC,EAAMD,EAAQ,IACpBA,EAAUP,EAAA,GAAKO,GACf,OAAOA,EAAQ,IAEf,GAAI,CACF,IAAMX,EAAM,IAAI,eAChBA,EAAI,KAAK,MAAOa,EAAK,MAAMD,EAAKD,CAAO,EAAG,EAAI,EAC9CX,EAAI,iBAAiB,SAAU,6DAA6D,EAC5FA,EAAI,iBAAiB,QAASF,EAAO,EACrCE,EAAI,iBAAiB,QAASK,CAAO,EACrCL,EAAI,iBAAiB,OAAQQ,EAAM,EACnCR,EAAI,KAAK,CACX,OAASc,EAAI,CACX,IAAMC,EAAU,0CAA0CD,EAAG,OAAO,GACpET,EAAQS,EAAI,CAAE,OAAQ,CAAE,QAAAC,CAAQ,CAAE,CAAC,CACrC,CACF,CAEA,IAAOC,EAAQ,CAAE,cAAAN,EAAc,EClD/B,SAASO,EAAIC,EAASC,EAAO,CAC3B,OAAAA,EAAQA,GAAS,CAAE,QAAS,CAAC,CAAE,EACxBD,EAAQ,MAAQC,EAAM,KAAOA,EAAM,QAAQ,eAAiB,SAAS,IAC9E,CAEA,SAASC,GAAKF,EAAS,CACrB,IAAIC,EAAQE,EAAS,2BAA2BH,CAAO,EAEjD,CAAE,WAAAI,EAAY,YAAAC,CAAY,EAAIL,EAAQ,QAE5C,OAAIA,EAAQ,QAAQ,YAAY,IAAM,OAC7B,CACL,KAAM,OACN,OAAQ,qBACR,MAAAC,EACA,IAAKD,EAAQ,OACb,cAAeM,EAAW,aAC5B,EAEED,GAAeA,EAAY,OAAS,EAC/B,CACL,KAAM,SACN,OAAQ,qCACR,MAAAJ,EACA,IAAKD,EAAQ,KACb,cAAeO,EAAa,aAC9B,EAGEH,GAAcA,IAAe,SAC/BH,EAAQ,SAAS,eAAeG,CAAU,EACnC,CACL,KAAM,QACN,OAAQ,4CACR,MAAAH,EACA,IAAKF,EAAIC,EAASC,CAAK,EACvB,cAAeO,EAAY,aAC7B,IAIG,CAACJ,GAAcA,IAAe,UAAYH,EACtC,CACL,KAAM,QACN,OAAQ,+EACR,MAAAA,EACA,IAAKF,EAAIC,EAASC,CAAK,EACvB,cAAeO,EAAY,aAC7B,EAMK,CACL,KAAM,SACN,OACE,+HACF,MAAO,KACP,IAAKT,EAAIC,CAAO,EAChB,cAAeS,EAAa,aAC9B,CACF,CAEA,IAAOC,EAAQ,CAAE,KAAAR,EAAK,ECpEtB,IAAIS,EAAe,UAEbC,EAAY,CAChB,MAAO,OAAO,OAAOC,CAAM,EAC3B,KAAM,OAAO,OAAOA,CAAM,EAC1B,KAAM,CAACA,EAAO,MAAOA,EAAO,YAAaA,EAAO,WAAW,EAC3D,MAAO,CAACA,EAAO,YAAaA,EAAO,WAAW,EAC9C,QAAS,CAAC,CACZ,EAEA,OAAO,OAAOA,CAAM,EAAE,QAAQC,GAAQ,CACpC,iBAAiBA,EAAMC,GAAS,CAC9B,GAAIH,EAAUD,CAAY,EAAE,SAASI,EAAM,IAAI,EAAG,CAChD,GAAM,CAAE,OAAAC,EAAQ,OAAAC,CAAO,EAAIF,EAC3B,QAAQJ,CAAY,EAAEI,EAAM,KAAM,CAAE,OAAAC,EAAQ,OAAAC,CAAO,CAAC,CACtD,CACF,CAAC,CACH,CAAC,EAED,IAAOC,EAAQ,CACb,IAAI,OAAQ,CACV,OAAOP,CACT,EACA,IAAI,MAAMQ,EAAO,CACf,OAAK,OAAO,KAAKP,CAAS,EAAE,SAASO,CAAK,IAAGA,EAAQ,WAC7CR,EAAeQ,CACzB,CACF,EC7BA,SAASC,IAAK,CACZ,OAAQ,0BAA6B,OAAO,QAAQ,SAAUC,IAC3DA,EAAK,OAAO,gBAAgB,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,EAAK,IAAOA,EAAI,GAAM,SAAS,EAAE,CACpF,CACF,CAEA,IAAOC,EAAQ,CAAE,GAAAF,EAAG,ECQpB,IAAMG,GAAa,KAAK,YAAc,CAAC,EAEjCC,EAAW,CACf,KAAM,GACN,aAAAC,EACA,OAAAC,EACA,OAAAC,EACA,OAAQC,EACR,sBAAuBC,EAAU,SACjC,IAAI,gBAAiB,CACnB,OAAOA,EAAU,MACnB,CACF,EAEA,SAASC,EAAoBC,EAAIC,EAAS,CACxC,MAAO,CACL,GAAAD,EACA,KAAMC,EAAQ,aAAaL,EAAO,gBAAgB,EAClD,UAAWK,EAAQ,GAAG,OAAS,EAAIA,EAAQ,GAAK,KAChD,kBAAmBC,EAAS,sBAAsBD,CAAO,EACzD,UAAW,KAAK,IAAI,EACpB,MAAOR,EAAS,MAChB,YAAaU,EAAM,OACnB,YAAaA,EAAM,OACrB,CACF,CAEA,eAAeC,GAAcC,EAAO,CAClC,IAAIJ,EACAK,EAAU,CAAC,EAEf,GAAI,CAGF,GAFAL,EAAUC,EAAS,mBAAmBG,EAAM,MAAM,EAC9C,CAACJ,GACD,CAACH,EAAU,uBAAuBO,EAAM,KAAMJ,CAAO,EAAG,OAE5D,IAAMM,EAAY,iBAAiBC,EAAM,GAAG,CAAC,GACzCC,EAASC,EAAQ,KAAKT,CAAO,EAC7BK,EAAUK,EAAAC,EAAA,GACTb,EAAoBQ,EAAWN,CAAO,GAD7B,CAEZ,OAAQQ,EAAO,KACf,QAASA,EAAO,MAAQA,EAAO,MAAM,GAAK,KAC1C,IAAKA,EAAO,GACd,GAEMI,EAAa,MAAMC,EAASjB,EAAc,MAAOI,EAAS,CAC9D,WAAY,GACZ,OAAQK,CACV,CAAC,EAED,GAAIO,EAAW,kBAAqBA,EAAW,OAAO,cAAgBR,EAAM,iBAC1E,OAAOS,EAASjB,EAAc,MAAOI,EAAS,CAC5C,OAAQ,CACN,QAAS,yBAAyBJ,EAAc,KAAK,+DACrD,OAAQgB,CACV,CACF,CAAC,EAkBH,OAfAJ,EAASC,EAAQ,KAAKT,CAAO,EAC7BK,EAAUK,EAAAC,EAAA,GACLb,EAAoBQ,EAAWN,CAAO,GADjC,CAER,OAAQQ,EAAO,KACf,QAASA,EAAO,MAAQA,EAAO,MAAM,GAAK,KAC1C,IAAKA,EAAO,GACd,GAEAM,EAAS,IAAIT,CAAO,EAEhB,CAAC,QAAS,QAAQ,EAAE,SAASG,EAAO,IAAI,GAAGJ,EAAM,eAAe,EAEpEZ,EAAS,KAAO,GAChB,WAAW,IAAOA,EAAS,KAAO,GAAQ,EAAE,EAEpCgB,EAAO,KAAM,CACnB,IAAK,SACH,OAAOA,EAAO,cAAcR,EAASK,CAAO,EAC9C,IAAK,OACH,OAAOG,EAAO,cAAcR,EAASK,EAASD,CAAK,EACrD,IAAK,QACH,OAAOI,EAAO,cAAcA,EAAO,MAAOH,CAAO,EACnD,IAAK,SACH,OAAOG,EAAO,cAAcH,CAAO,CACvC,CACF,OAASU,EAAO,CACdF,EAASjB,EAAc,YAAaI,EAAS,CAC3C,OAAQU,EAAAC,EAAA,GAAKN,GAAL,CAAc,MAAAU,CAAM,EAC9B,CAAC,CACH,CACF,CAEA,KAAK,WAAaJ,EAAA,GAAKpB,IAElB,KAAK,WAAW,WAEnBM,EAAU,QAAUM,GACpBN,EAAU,SAAS,QAAS,CAAC,IAAIF,EAAO,gBAAgB,GAAG,CAAC,EAC5DE,EAAU,SAAS,SAAU,CAAC,QAAQF,EAAO,gBAAgB,GAAG,CAAC,EACjEE,EAAU,SAAS,SAAU,CAC3B,SAASF,EAAO,gBAAgB,IAChC,UAAUA,EAAO,gBAAgB,IACjC,YAAYA,EAAO,gBAAgB,GACrC,CAAC,EAED,KAAK,WAAW,SAAWH,EAC3B,KAAK,WAAW,MAAQU,GAG1B,IAAOc,GAAQxB",
6
+ "names": ["commandEvents", "stateEvents", "allEvents", "__spreadValues", "dispatch", "name", "target", "options", "resolve", "evt", "__spreadProps", "head", "observable", "object", "parent", "proxy", "target", "key", "dispatch", "stateEvents", "value", "receiver", "index", "observable_default", "initialState", "currentState", "changedState", "signedState", "initialize", "initial", "signed", "json", "__spreadValues", "observable_default", "dispatch", "stateEvents", "event", "key", "value", "state_default", "replaceDocument", "content", "head", "tail", "headIndex", "tailIndex", "html", "append", "renderer_default", "active", "add", "payload", "remove", "id", "activity_default", "finish", "event", "dispatch", "commandEvents", "activity_default", "lifecycle_default", "frameSources", "event", "_a", "_b", "frame", "fetchOptions", "acceptHeaders", "entry", "response", "error", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "content", "renderer_default", "schema", "schema_default", "__spreadValues", "confirmation", "message", "isTurboMethod", "event", "isTurboForm", "element", "frame", "target", "schema_default", "shouldDelegate", "commandEvents", "confirmation_default", "events", "eventListener", "register", "eventName", "selectors", "match", "evt", "__spreadValues", "getRegisteredEventForElement", "element", "selector", "el", "isRegisteredForElement", "delegates_default", "fn", "findClosestCommand", "element", "schema_default", "findClosestFrameWithSource", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "value", "elements_default", "invokeCommand", "form", "payload", "event", "input", "form_default", "build", "urlString", "payload", "a", "url", "urls_default", "invokeCommand", "frame", "payload", "src", "__spreadValues", "urls_default", "frame_default", "invokeCommand", "element", "payload", "src", "__spreadValues", "urls_default", "method_default", "aborted", "event", "xhr", "dispatch", "lifecycle_default", "__spreadProps", "__spreadValues", "errored", "renderer_default", "error", "loaded", "content", "invokeCommand", "payload", "src", "urls_default", "ex", "message", "window_default", "src", "element", "frame", "find", "elements_default", "turboFrame", "turboMethod", "form_default", "method_default", "frame_default", "window_default", "drivers_default", "currentLevel", "logLevels", "allEvents", "name", "event", "target", "detail", "logger_default", "value", "v4", "c", "uuids_default", "TurboBoost", "Commands", "confirmation_default", "logger_default", "schema_default", "commandEvents", "delegates_default", "buildCommandPayload", "id", "element", "elements_default", "state_default", "invokeCommand", "event", "payload", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "activity_default", "error", "javascript_default"]
7
7
  }
@@ -5,7 +5,7 @@ module TurboBoost::Commands::Controller
5
5
 
6
6
  module ClassMethods
7
7
  def turbo_boost_state(&block)
8
- TurboBoost::State::Manager.add_state_override_block name, block
8
+ TurboBoost::Commands::State.assign_resolver(&block)
9
9
  end
10
10
  end
11
11
 
@@ -1,7 +1,4 @@
1
- import meta from '../meta'
2
-
3
1
  function invokeCommand(form, payload = {}, event = {}) {
4
- payload.token = meta.token
5
2
  const input = form.querySelector('input[name="turbo_boost_command"]') || document.createElement('input')
6
3
  input.type = 'hidden'
7
4
  input.name = 'turbo_boost_command'
@@ -1,4 +1,3 @@
1
- import meta from '../meta'
2
1
  import state from '../state'
3
2
  import { dispatch } from '../events'
4
3
  import lifecycle from '../lifecycle'
@@ -45,11 +44,6 @@ function invokeCommand(payload) {
45
44
  const xhr = new XMLHttpRequest()
46
45
  xhr.open('GET', urls.build(src, payload), true)
47
46
  xhr.setRequestHeader('Accept', 'text/vnd.turbo-boost.html, text/html, application/xhtml+xml')
48
- xhr.setRequestHeader('TurboBoost-Token', meta.token)
49
- state.payloadChunks.forEach((chunk, i) =>
50
- xhr.setRequestHeader(`TurboBoost-State-${i.toString().padStart(4, '0')}`, chunk)
51
- )
52
-
53
47
  xhr.addEventListener('abort', aborted)
54
48
  xhr.addEventListener('error', errored)
55
49
  xhr.addEventListener('load', loaded)
@@ -1,11 +1,10 @@
1
1
  import './turbo'
2
2
  import schema from './schema'
3
- import { dispatch, commandEvents, stateEvents } from './events'
3
+ import { dispatch, commandEvents } from './events'
4
4
  import activity from './activity'
5
5
  import confirmation from './confirmation'
6
6
  import delegates from './delegates'
7
7
  import drivers from './drivers'
8
- import meta from './meta'
9
8
  import elements from './elements'
10
9
  import lifecycle from './lifecycle'
11
10
  import logger from './logger'
@@ -13,13 +12,30 @@ import state from './state'
13
12
  import urls from './urls'
14
13
  import uuids from './uuids'
15
14
 
15
+ const TurboBoost = self.TurboBoost || {}
16
+
17
+ const Commands = {
18
+ busy: false,
19
+ confirmation,
20
+ logger,
21
+ schema,
22
+ events: commandEvents,
23
+ registerEventDelegate: delegates.register,
24
+ get eventDelegates() {
25
+ return delegates.events
26
+ }
27
+ }
28
+
16
29
  function buildCommandPayload(id, element) {
17
30
  return {
18
31
  id, // uniquely identifies the command
19
32
  name: element.getAttribute(schema.commandAttribute),
20
33
  elementId: element.id.length > 0 ? element.id : null,
21
34
  elementAttributes: elements.buildAttributePayload(element),
22
- startedAt: Date.now()
35
+ startedAt: Date.now(),
36
+ token: Commands.token, // command token (used for CSRF protection)
37
+ signedState: state.signed, // server side state
38
+ clientState: state.changed // client side state (delta of optimistic updates)
23
39
  }
24
40
  }
25
41
 
@@ -67,8 +83,8 @@ async function invokeCommand(event) {
67
83
 
68
84
  if (['frame', 'window'].includes(driver.name)) event.preventDefault()
69
85
 
70
- meta.busy = true
71
- setTimeout(() => (meta.busy = false), 10)
86
+ Commands.busy = true
87
+ setTimeout(() => (Commands.busy = false), 10)
72
88
 
73
89
  switch (driver.name) {
74
90
  case 'method':
@@ -87,21 +103,7 @@ async function invokeCommand(event) {
87
103
  }
88
104
  }
89
105
 
90
- self.TurboBoost = self.TurboBoost || {}
91
-
92
- self.TurboBoost = {
93
- ...self.TurboBoost,
94
-
95
- stateEvents,
96
-
97
- get state() {
98
- return state.current
99
- },
100
-
101
- get stateDelta() {
102
- return state.delta
103
- }
104
- }
106
+ self.TurboBoost = { ...TurboBoost }
105
107
 
106
108
  if (!self.TurboBoost.Commands) {
107
109
  // wire things up and setup defaults for event delegation
@@ -114,16 +116,8 @@ if (!self.TurboBoost.Commands) {
114
116
  `textarea[${schema.commandAttribute}]`
115
117
  ])
116
118
 
117
- self.TurboBoost.Commands = {
118
- confirmation,
119
- logger,
120
- schema,
121
- events: commandEvents,
122
- registerEventDelegate: delegates.register,
123
- get eventDelegates() {
124
- return delegates.events
125
- }
126
- }
119
+ self.TurboBoost.Commands = Commands
120
+ self.TurboBoost.State = state
127
121
  }
128
122
 
129
- export default self.TurboBoost.Commands
123
+ export default Commands
@@ -1,62 +1,44 @@
1
- import meta from '../meta'
1
+ // TODO: Consider moving State to its own library
2
2
  import observable from './observable'
3
3
  import { dispatch, commandEvents, stateEvents } from '../events'
4
4
 
5
- let loadedState, currentState, changedState
6
- let loadStateTimeout
5
+ let initialState, currentState, changedState, signedState
7
6
 
8
- function loadState() {
9
- if (!meta.element) return loadStateLater()
10
- const json = atob(meta.element.dataset.state)
7
+ function initialize(initial, signed) {
8
+ const json = JSON.parse(initial)
9
+ initialState = { ...json }
10
+ signedState = signed
11
+ currentState = observable(json)
11
12
  changedState = {}
12
- currentState = observable(JSON.parse(json))
13
- loadedState = { ...currentState }
14
- delete meta.element.dataset.clientStateChange
15
13
  setTimeout(() =>
16
- dispatch(stateEvents.stateLoad, meta.element, {
14
+ dispatch(stateEvents.stateLoad, document, {
17
15
  detail: { state: currentState }
18
16
  })
19
17
  )
20
18
  }
21
19
 
22
- function loadStateLater() {
23
- clearTimeout(loadStateTimeout)
24
- loadStateTimeout = setTimeout(loadState, 10)
25
- }
26
-
27
- if (!loadedState) loadState()
28
-
29
- addEventListener('DOMContentLoaded', loadStateLater)
30
- addEventListener('load', loadStateLater)
31
- addEventListener('turbo:load', loadStateLater)
32
- addEventListener('turbo:frame-load', loadStateLater)
33
- addEventListener(commandEvents.success, loadStateLater)
34
-
35
20
  addEventListener(stateEvents.stateChange, event => {
36
- changedState = {}
37
21
  for (const [key, value] of Object.entries(currentState))
38
- if (loadedState[key] !== value) changedState[key] = value
39
- meta.element.dataset.clientStateChange = true
40
- meta.element.dataset.state = btoa(JSON.stringify(currentState))
22
+ if (initialState[key] !== value) changedState[key] = value
41
23
  })
42
24
 
43
25
  export default {
26
+ initialize,
44
27
  events: stateEvents,
45
28
 
29
+ get initial() {
30
+ return initialState
31
+ },
32
+
46
33
  get current() {
47
34
  return currentState
48
35
  },
49
36
 
50
- get delta() {
37
+ get changed() {
51
38
  return changedState
52
39
  },
53
40
 
54
- // The UI state changes are split into chunks and sent to the server in an HTTP request header.
55
- // Max size for an HTTP header is around 4k or 4,000 bytes.
56
- // A Base64 character is an 8-bit-padded ASCII character... or 1 byte
57
- //
58
- // SEE: lib/state.rb - for info on how `state` is serialized/deserialized
59
- get payloadChunks() {
60
- return btoa(JSON.stringify(changedState)).match(/.{1,2000}/g)
41
+ get signed() {
42
+ return signedState
61
43
  }
62
44
  }
@@ -1,4 +1,3 @@
1
- import meta from '../meta'
2
1
  import { dispatch, stateEvents as events } from '../events'
3
2
 
4
3
  let head
@@ -9,13 +8,13 @@ function observable(object, parent = null) {
9
8
  const proxy = new Proxy(object, {
10
9
  deleteProperty(target, key) {
11
10
  delete target[key]
12
- dispatch(events.stateChange, meta.element, { detail: { state: head } })
11
+ dispatch(events.stateChange, document, { detail: { state: head } })
13
12
  return true
14
13
  },
15
14
 
16
15
  set(target, key, value, receiver) {
17
16
  target[key] = observable(value, this)
18
- dispatch(events.stateChange, meta.element, { detail: { state: head } })
17
+ dispatch(events.stateChange, document, { detail: { state: head } })
19
18
  return true
20
19
  }
21
20
  })
@@ -1,4 +1,3 @@
1
- import meta from './meta'
2
1
  import state from './state'
3
2
  import renderer from './renderer'
4
3
  import { dispatch } from './events'
@@ -12,17 +11,11 @@ addEventListener('turbo:before-fetch-request', event => {
12
11
  const { fetchOptions } = event.detail
13
12
 
14
13
  // command invoked and busy
15
- if (meta.busy) {
14
+ if (self.TurboBoost?.Commands?.busy) {
16
15
  let acceptHeaders = ['text/vnd.turbo-boost.html', fetchOptions.headers['Accept']]
17
16
  acceptHeaders = acceptHeaders.filter(entry => entry && entry.trim().length > 0).join(', ')
18
17
  fetchOptions.headers['Accept'] = acceptHeaders
19
- fetchOptions.headers['TurboBoost-Token'] = meta.token
20
18
  }
21
-
22
- // always send state
23
- state.payloadChunks.forEach((chunk, i) => {
24
- fetchOptions.headers[`TurboBoost-State-${i.toString().padStart(4, '0')}`] = chunk
25
- })
26
19
  })
27
20
 
28
21
  // fires after receiving a turbo HTTP response
@@ -2,7 +2,7 @@ function build(urlString, payload = {}) {
2
2
  const a = document.createElement('a')
3
3
  a.href = urlString
4
4
  const url = new URL(a)
5
- url.searchParams.set('turbo_boost_command', JSON.stringify(payload))
5
+ url.searchParams.set('tbc', JSON.stringify(payload))
6
6
  return url
7
7
  }
8
8
 
@@ -77,17 +77,15 @@ class TurboBoost::Commands::Command
77
77
  end
78
78
  end
79
79
 
80
- attr_reader :controller, :state_manager, :params, :turbo_streams
81
-
82
- alias_method :state, :state_manager
80
+ attr_reader :controller, :state, :params, :turbo_streams
83
81
  alias_method :streams, :turbo_streams
84
82
 
85
83
  delegate :css_id_selector, to: :"self.class"
86
84
  delegate :dom_id, to: :"controller.view_context"
87
85
 
88
- def initialize(controller, state_manager, params = {})
86
+ def initialize(controller, state, params = {})
89
87
  @controller = controller
90
- @state_manager = state_manager
88
+ @state = state
91
89
  @params = params
92
90
  @turbo_streams = Set.new
93
91
  end