From 0cc4a464e239b47a4431cea775e3752a287defcd Mon Sep 17 00:00:00 2001 From: "Nate Hopkins (hopsoft)" Date: Sat, 10 Feb 2024 13:03:55 -0700 Subject: [PATCH] More work to remove cookie and header state management --- app/assets/builds/@turbo-boost/commands.js | 2 +- .../builds/@turbo-boost/commands.js.map | 6 +- .../@turbo-boost/commands.metafile.json | 2 +- .../turbo_boost/commands/controller.rb | 2 +- app/javascript/index.js | 10 +- app/javascript/meta.js | 25 +--- app/javascript/state/index.js | 13 +- docker-compose.yml | 1 - lib/turbo_boost/commands/controller_pack.rb | 1 - lib/turbo_boost/commands/engine.rb | 1 - lib/turbo_boost/commands/errors.rb | 2 + lib/turbo_boost/commands/runner.rb | 25 ++-- lib/turbo_boost/{ => commands}/state.rb | 22 ++- lib/turbo_boost/errors.rb | 6 - lib/turbo_boost/state/errors.rb | 6 - lib/turbo_boost/state/manager.rb | 134 ------------------ lib/turbo_boost/state/provisional_state.rb | 31 ---- test/dummy/config/importmap.rb | 4 +- test/state_test.rb | 26 ++-- .../basic_commands/turbo_boost_setup_test.rb | 10 +- turbo_boost-commands.gemspec | 2 +- 21 files changed, 80 insertions(+), 251 deletions(-) rename lib/turbo_boost/{ => commands}/state.rb (69%) delete mode 100644 lib/turbo_boost/errors.rb delete mode 100644 lib/turbo_boost/state/errors.rb delete mode 100644 lib/turbo_boost/state/manager.rb delete mode 100644 lib/turbo_boost/state/provisional_state.rb diff --git a/app/assets/builds/@turbo-boost/commands.js b/app/assets/builds/@turbo-boost/commands.js index 17029c3b..8b8e6b0c 100644 --- a/app/assets/builds/@turbo-boost/commands.js +++ b/app/assets/builds/@turbo-boost/commands.js @@ -1,2 +1,2 @@ -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 N=(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)&&N(e,r,t[r]);if(I)for(var r of I(t))oe.call(t,r)&&N(e,r,t[r]);return e},u=(e,t)=>ee(e,te(t));var S=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=!1){return this.element.dataset.busy=!!t}get client(){return JSON.parse(this.element.dataset.client)}set client(t={}){return this.element.dataset.client=JSON.stringify(t)}get delta(){return this.element.dataset.delta?JSON.parse(this.element.dataset.delta):{}}set delta(t={}){return this.element.dataset.delta=JSON.stringify(t)}get server(){return this.element.dataset.server}},a=new S;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 O;function T(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:O}}),!0},set(o,n,c,y){return o[n]=T(c,this),d(l.stateChange,a.element,{detail:{state:O}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=T(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=T(n,r);return t||(O=r),r}var X=T;var B,x,E,F;function J(){if(!a.element)return v();let e=JSON.parse(a.element.dataset.client);B=s({},e),x=X(e),E={},setTimeout(()=>d(l.stateLoad,a.element,{detail:{state:x}}))}function v(){clearTimeout(F),F=setTimeout(J,10)}B||J();addEventListener("DOMContentLoaded",v);addEventListener("load",v);addEventListener("turbo:load",v);addEventListener("turbo:frame-load",v);addEventListener(i.success,v);addEventListener(l.stateChange,e=>{E={};for(let[t,r]of Object.entries(x))B[t]!==r&&(E[t]=r);a.client=x,a.delta=E});var D={events:l,get current(){return x},get delta(){return E}};function ne(e){let t="=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 h={append:se,replaceDocument:ne};var k={};function ae(e){k[e.id]=e}function ie(e){delete k[e]}var L={add:ae,remove:ie,get commands(){return[...Object.values(k)]},get length(){return Object.keys(k).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=>L.remove(e.detail.id),!0);var C={events:i};var P={};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}});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(P[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(C.events.clientError,document,{detail:u(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=P[t.id]||t.src||t.dataset.turboBoostSrc,delete P[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=[],R;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,R,!0),document.addEventListener(e,R,!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){R=e}};function pe(e){return e.closest(`[${m.commandAttribute}]`)}function ve(e){return e.closest("turbo-frame[src]")||e.closest("turbo-frame[data-turbo-frame-src]")||e.closest("turbo-frame")}function he(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,he(e,t),delete t.class,delete t.action,delete t.href,delete t[m.commandAttribute],delete t[m.frameAttribute],t}var A={buildAttributePayload:ge,findClosestCommand:pe,findClosestFrameWithSource:ve};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 g={build:xe};function Ce(e,t){let r=t.src;t=s({},t),delete t.src,e.src=g.build(r,t)}var $={invokeCommand:Ce};function Ae(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",g.build(r,t))}var V={invokeCommand:Ae};function ye(e){let t=e.target;d(C.events.abort,document,{detail:u(s({},e.detail),{xhr:t})})}function _(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.`;d(C.events.clientError,document,{detail:u(s({},e.detail),{error:o,xhr:t})},!0)}function Te(e){let t=e.target;if(t.status<200||t.status>399)return _(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 ke(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",g.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.addEventListener("abort",ye),r.addEventListener("error",_),r.addEventListener("load",Te),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;_(r,{detail:{message:o}})}}var G={invokeCommand:ke};function H(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Le(e){let t=A.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:H(e,t),invokeCommand:$.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:H(e,t),invokeCommand:$.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:H(e),invokeCommand:G.invokeCommand}}var q={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 we(){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:we};function Y(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:A.buildAttributePayload(t),startedAt:Date.now(),token:a.token,state:{delta:a.delta,server:a.server}}}async function Se(e){let t,r={};try{if(t=A.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${Q.v4()}`,n=q.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),y=await d(i.start,t,{cancelable:!0,detail:c});if(y.defaultPrevented||y.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:y}});switch(n=q.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),L.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 D.current},get stateDelta(){return D.delta}});self.TurboBoost.Commands||(p.handler=Se,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 er=self.TurboBoost.Commands;export{er as default}; +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=!1){return this.element.dataset.busy=!!t}get state(){return this.element.dataset.state}get signedState(){return this.element.dataset.signedState}},i=new O;var a={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"},l=s(s({},a),f);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 A(e,t=null){if(!e||typeof e!="object")return e;let r=new Proxy(e,{deleteProperty(o,n){return delete o[n],d(f.stateChange,i.element,{detail:{state:B}}),!0},set(o,n,c,C){return o[n]=A(c,this),d(f.stateChange,i.element,{detail:{state:B}}),!0}});if(Array.isArray(e))e.forEach((o,n)=>e[n]=A(o,r));else if(typeof e=="object")for(let[o,n]of Object.entries(e))e[o]=A(n,r);return t||(B=r),r}var F=A;var T,y,D,M;function N(){if(!i.element)return h();let e=JSON.parse(i.element.dataset.state);T=s({},e),y=F(e),D={},setTimeout(()=>d(f.stateLoad,i.element,{detail:{state:y}}))}function h(){clearTimeout(M),M=setTimeout(N,10)}T||N();addEventListener("DOMContentLoaded",h);addEventListener("load",h);addEventListener("turbo:load",h);addEventListener("turbo:frame-load",h);addEventListener(a.success,h);addEventListener(f.stateChange,e=>{for(let[t,r]of Object.entries(y))T[t]!==r&&(D[t]=r)});var k={events:f,get initial(){return s({},T)},get current(){return y},get changed(){return s({},D)}};function ne(e){let t="=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 v={append:se,replaceDocument:ne};var L={};function ae(e){L[e.id]=e}function ie(e){delete L[e]}var w={add:ae,remove:ie,get commands(){return[...Object.values(L)]},get length(){return Object.keys(L).length}};function j(e){e.detail.endedAt=Date.now(),e.detail.milliseconds=e.detail.endedAt-e.detail.startedAt,setTimeout(()=>d(a.finish,e.target,{detail:e.detail}),25)}addEventListener(a.serverError,j);addEventListener(a.success,j);addEventListener(a.finish,e=>w.remove(e.detail.id),!0);var E={events:a};var P={};addEventListener("turbo:before-fetch-request",e=>{let t=e.target.closest("turbo-frame"),{fetchOptions:r}=e.detail;if(i.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}});addEventListener("turbo:before-fetch-response",e=>{let t=e.target.closest("turbo-frame"),{fetchResponse:r}=e.detail;if(t&&(P[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(E.events.clientError,document,{detail:u(s({},e.detail),{error:o})},!0)}r.header("TurboBoost")==="Append"&&(e.preventDefault(),r.responseText.then(o=>v.append(o)))}});addEventListener("turbo:frame-load",e=>{let t=e.target.closest("turbo-frame");t.dataset.turboBoostSrc=P[t.id]||t.src||t.dataset.turboBoostSrc,delete P[t.id]});var de={frameAttribute:"data-turbo-frame",methodAttribute:"data-turbo-method",commandAttribute:"data-turbo-command",confirmAttribute:"data-turbo-confirm"},m=s({},de);var W={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(a.start,async e=>{let t=e.target.getAttribute(m.confirmAttribute);if(!t||(e.detail.confirmation=!0,ce(e)))return;await W.method(t)||e.preventDefault()});var J=W;var b=[],R;function fe(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,R,!0),document.addEventListener(e,R,!0),s({},b.find(o=>o.name===e))}function le(e){return b.find(t=>t.selectors.find(r=>Array.from(document.querySelectorAll(r)).find(o=>o===e)))}function be(e,t){let r=le(t);return r&&r.name===e}var p={register:fe,isRegisteredForElement:be,get events(){return[...b]},set handler(e){R=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 x={buildAttributePayload:ge,findClosestCommand:pe,findClosestFrameWithSource:he};function Ee(e,t={},r={}){t.token=i.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 g={build:xe};function Ce(e,t){let r=t.src;t=s({},t),delete t.src,e.src=g.build(r,t)}var $={invokeCommand:Ce};function Ae(e,t={}){let r=t.src;t=s({},t),delete t.src,delete t.href,e.setAttribute("href",g.build(r,t))}var V={invokeCommand:Ae};function ye(e){let t=e.target;d(E.events.abort,document,{detail:u(s({},e.detail),{xhr:t})})}function _(e){let t=e.target;(t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html"))&&v.append(t.responseText);let o=`Server returned a ${t.status} status code! TurboBoost Commands require 2XX-3XX status codes.`;d(E.events.clientError,document,{detail:u(s({},e.detail),{error:o,xhr:t})},!0)}function Te(e){let t=e.target;if(t.status<200||t.status>399)return _(e);let r=t.responseText;t.getResponseHeader("TurboBoost")==="Append"||t.getResponseHeader("Content-Type").startsWith("text/vnd.turbo-boost.html")?v.append(t.responseText):v.replaceDocument(t.responseText)}function ke(e){let t=e.src;e=s({},e),delete e.src;try{let r=new XMLHttpRequest;r.open("GET",g.build(t,e),!0),r.setRequestHeader("Accept","text/vnd.turbo-boost.html, text/html, application/xhtml+xml"),r.addEventListener("abort",ye),r.addEventListener("error",_),r.addEventListener("load",Te),r.send()}catch(r){let o=`Unexpected error sending HTTP request! ${r.message}`;_(r,{detail:{message:o}})}}var G={invokeCommand:ke};function H(e,t){return t=t||{dataset:{}},e.href||t.src||t.dataset.turboBoostSrc||location.href}function Le(e){let t=x.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:H(e,t),invokeCommand:$.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:H(e,t),invokeCommand:$.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:H(e),invokeCommand:G.invokeCommand}}var q={find:Le};var S="unknown",z={debug:Object.values(l),info:Object.values(l),warn:[l.abort,l.clientError,l.serverError],error:[l.clientError,l.serverError],unknown:[]};Object.values(l).forEach(e=>{addEventListener(e,t=>{if(z[S].includes(t.type)){let{target:r,detail:o}=t;console[S](t.type,{target:r,detail:o})}})});var K={get level(){return S},set level(e){return Object.keys(z).includes(e)||(e="unknown"),S=e}};function we(){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:we};function Y(e,t){return{id:e,name:t.getAttribute(m.commandAttribute),elementId:t.id.length>0?t.id:null,elementAttributes:x.buildAttributePayload(t),startedAt:Date.now(),token:i.token,signedState:i.signedState,state:k.changed}}async function Se(e){let t,r={};try{if(t=x.findClosestCommand(e.target),!t||!p.isRegisteredForElement(e.type,t))return;let o=`turbo-command-${Q.v4()}`,n=q.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),C=await d(a.start,t,{cancelable:!0,detail:c});if(C.defaultPrevented||C.detail.confirmation&&e.defaultPrevented)return d(a.abort,t,{detail:{message:`An event handler for '${a.start}' prevented default behavior and blocked command invocation!`,source:C}});switch(n=q.find(t),c=u(s({},Y(o,t)),{driver:n.name,frameId:n.frame?n.frame.id:null,src:n.src}),w.add(c),["frame","window"].includes(n.name)&&e.preventDefault(),i.busy=!0,setTimeout(()=>i.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(a.clientError,t,{detail:u(s({},r),{error:o})})}}self.TurboBoost=self.TurboBoost||{};self.TurboBoost=u(s({},self.TurboBoost),{stateEvents:f,get state(){return k.current},get stateChanges(){return k.changed}});self.TurboBoost.Commands||(p.handler=Se,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:J,logger:K,schema:m,events:a,registerEventDelegate:p.register,get eventDelegates(){return p.events}});var er=self.TurboBoost.Commands;export{er as default}; //# sourceMappingURL=commands.js.map diff --git a/app/assets/builds/@turbo-boost/commands.js.map b/app/assets/builds/@turbo-boost/commands.js.map index dccb7df8..5142290e 100644 --- a/app/assets/builds/@turbo-boost/commands.js.map +++ b/app/assets/builds/@turbo-boost/commands.js.map @@ -1,7 +1,7 @@ { "version": 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"], - "sourcesContent": ["class Meta {\n get element() {\n return document.querySelector('meta[name=\"turbo-boost\"]')\n }\n\n // token that can be used to verify the authenticity of a command\n get token() {\n return this.element.getAttribute('content')\n }\n\n // indicates if a command is active\n get busy() {\n return this.element.dataset.busy === 'true'\n }\n\n set busy(value = false) {\n return (this.element.dataset.busy = !!value)\n }\n\n // mutable and optimistic client side state\n get client() {\n return JSON.parse(this.element.dataset.client)\n }\n\n set client(value = {}) {\n return (this.element.dataset.client = JSON.stringify(value))\n }\n\n // mutable and optimistic client side state\n get delta() {\n return this.element.dataset.delta ? JSON.parse(this.element.dataset.delta) : {}\n }\n\n set delta(value = {}) {\n return (this.element.dataset.delta = JSON.stringify(value))\n }\n\n // immutable server side state - from the last command\n get server() {\n return this.element.dataset.server\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 initialState, currentState, changedState\nlet loadStateTimeout\n\nfunction loadState() {\n if (!meta.element) return loadStateLater()\n const json = JSON.parse(meta.element.dataset.client)\n initialState = { ...json }\n currentState = observable(json)\n changedState = {}\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 (!initialState) 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 (initialState[key] !== value) changedState[key] = value\n meta.client = currentState\n meta.delta = changedState\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", "function replaceDocument(content) {\n const head = '= 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 }\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.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 token: meta.token, // authenticity token\n state: {\n delta: meta.delta, // client side state changes (optimistic updates)\n server: meta.server // server side state when the last command performed\n }\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"], - "mappings": "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", - "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", "initialState", "currentState", "changedState", "loadStateTimeout", "loadState", "meta_default", "loadStateLater", "json", "__spreadValues", "observable_default", "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", "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", "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", "meta_default", "invokeCommand", "event", "payload", "delegates_default", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "commandEvents", "activity_default", "error", "stateEvents", "state_default", "confirmation_default", "logger_default", "javascript_default"] + "sourcesContent": ["class Meta {\n get element() {\n return document.querySelector('meta[name=\"turbo-boost\"]')\n }\n\n // token that can be used to verify the authenticity of a command\n get token() {\n return this.element.getAttribute('content')\n }\n\n // indicates if a command is active\n get busy() {\n return this.element.dataset.busy === 'true'\n }\n\n set busy(value = false) {\n return (this.element.dataset.busy = !!value)\n }\n\n // mutable state representation for use on the client\n get state() {\n return this.element.dataset.state\n }\n\n // signed and immutable server state determined by the last command\n get signedState() {\n return this.element.dataset.signedState\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 initialState, currentState, changedState\nlet loadStateTimeout\n\nfunction loadState() {\n if (!meta.element) return loadStateLater()\n const json = JSON.parse(meta.element.dataset.state)\n initialState = { ...json }\n currentState = observable(json)\n changedState = {}\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 (!initialState) 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 for (const [key, value] of Object.entries(currentState))\n if (initialState[key] !== value) changedState[key] = value\n})\n\nexport default {\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", "function replaceDocument(content) {\n const head = '= 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 }\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.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 token: meta.token, // authenticity token\n signedState: meta.signedState, // server side state\n state: state.changed // client side state (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 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 stateChanges() {\n return state.changed\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"], + "mappings": "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", + "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", "initialState", "currentState", "changedState", "loadStateTimeout", "loadState", "meta_default", "loadStateLater", "json", "__spreadValues", "observable_default", "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", "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", "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", "meta_default", "state_default", "invokeCommand", "event", "payload", "delegates_default", "commandId", "uuids_default", "driver", "drivers_default", "__spreadProps", "__spreadValues", "startEvent", "dispatch", "commandEvents", "activity_default", "error", "stateEvents", "confirmation_default", "logger_default", "javascript_default"] } diff --git a/app/assets/builds/@turbo-boost/commands.metafile.json b/app/assets/builds/@turbo-boost/commands.metafile.json index 7a1b7c8d..e439af53 100644 --- a/app/assets/builds/@turbo-boost/commands.metafile.json +++ b/app/assets/builds/@turbo-boost/commands.metafile.json @@ -1 +1 @@ -{"inputs":{"app/javascript/meta.js":{"bytes":1031,"imports":[],"format":"esm"},"app/javascript/events.js":{"bytes":783,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/state/observable.js":{"bytes":920,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"}],"format":"esm"},"app/javascript/state/index.js":{"bytes":1312,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/observable.js","kind":"import-statement","original":"./observable"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/renderer.js":{"bytes":475,"imports":[],"format":"esm"},"app/javascript/activity.js":{"bytes":279,"imports":[],"format":"esm"},"app/javascript/lifecycle.js":{"bytes":610,"imports":[{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/turbo.js":{"bytes":1791,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"./renderer"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/schema.js":{"bytes":226,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/confirmation.js":{"bytes":947,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"}],"format":"esm"},"app/javascript/delegates.js":{"bytes":923,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/elements.js":{"bytes":1451,"imports":[{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"}],"format":"esm"},"app/javascript/drivers/form.js":{"bytes":384,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"}],"format":"esm"},"app/javascript/urls.js":{"bytes":240,"imports":[],"format":"esm"},"app/javascript/drivers/frame.js":{"bytes":218,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/method.js":{"bytes":265,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/window.js":{"bytes":1893,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"../state"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"../lifecycle"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"../renderer"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/index.js":{"bytes":2044,"imports":[{"path":"app/javascript/elements.js","kind":"import-statement","original":"../elements"},{"path":"app/javascript/drivers/form.js","kind":"import-statement","original":"./form"},{"path":"app/javascript/drivers/frame.js","kind":"import-statement","original":"./frame"},{"path":"app/javascript/drivers/method.js","kind":"import-statement","original":"./method"},{"path":"app/javascript/drivers/window.js","kind":"import-statement","original":"./window"}],"format":"esm"},"app/javascript/logger.js":{"bytes":729,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/uuids.js":{"bytes":202,"imports":[],"format":"esm"},"app/javascript/index.js":{"bytes":3777,"imports":[{"path":"app/javascript/turbo.js","kind":"import-statement","original":"./turbo"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/confirmation.js","kind":"import-statement","original":"./confirmation"},{"path":"app/javascript/delegates.js","kind":"import-statement","original":"./delegates"},{"path":"app/javascript/drivers/index.js","kind":"import-statement","original":"./drivers"},{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/elements.js","kind":"import-statement","original":"./elements"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"app/javascript/logger.js","kind":"import-statement","original":"./logger"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"./urls"},{"path":"app/javascript/uuids.js","kind":"import-statement","original":"./uuids"},{"path":"","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/commands.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":35173},"app/assets/builds/@turbo-boost/commands.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"app/javascript/meta.js":{"bytesInOutput":1037},"app/javascript/events.js":{"bytesInOutput":816},"app/javascript/state/observable.js":{"bytesInOutput":888},"app/javascript/state/index.js":{"bytesInOutput":1286},"app/javascript/renderer.js":{"bytesInOutput":491},"app/javascript/activity.js":{"bytesInOutput":288},"app/javascript/lifecycle.js":{"bytesInOutput":489},"app/javascript/turbo.js":{"bytesInOutput":1534},"app/javascript/schema.js":{"bytesInOutput":244},"app/javascript/confirmation.js":{"bytesInOutput":886},"app/javascript/delegates.js":{"bytesInOutput":968},"app/javascript/elements.js":{"bytesInOutput":1369},"app/javascript/drivers/form.js":{"bytesInOutput":374},"app/javascript/urls.js":{"bytesInOutput":249},"app/javascript/drivers/frame.js":{"bytesInOutput":239},"app/javascript/drivers/method.js":{"bytesInOutput":288},"app/javascript/drivers/window.js":{"bytesInOutput":1871},"app/javascript/drivers/index.js":{"bytesInOutput":1616},"app/javascript/logger.js":{"bytesInOutput":724},"app/javascript/uuids.js":{"bytesInOutput":208},"app/javascript/index.js":{"bytesInOutput":3606}},"bytes":21076}}} \ No newline at end of file +{"inputs":{"app/javascript/meta.js":{"bytes":707,"imports":[],"format":"esm"},"app/javascript/events.js":{"bytes":783,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/state/observable.js":{"bytes":920,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"}],"format":"esm"},"app/javascript/state/index.js":{"bytes":1298,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/observable.js","kind":"import-statement","original":"./observable"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/renderer.js":{"bytes":475,"imports":[],"format":"esm"},"app/javascript/activity.js":{"bytes":279,"imports":[],"format":"esm"},"app/javascript/lifecycle.js":{"bytes":610,"imports":[{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/turbo.js":{"bytes":1733,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"./renderer"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/schema.js":{"bytes":226,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/confirmation.js":{"bytes":947,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"}],"format":"esm"},"app/javascript/delegates.js":{"bytes":923,"imports":[{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/elements.js":{"bytes":1451,"imports":[{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"}],"format":"esm"},"app/javascript/drivers/form.js":{"bytes":384,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"}],"format":"esm"},"app/javascript/urls.js":{"bytes":240,"imports":[],"format":"esm"},"app/javascript/drivers/frame.js":{"bytes":218,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/method.js":{"bytes":265,"imports":[{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/window.js":{"bytes":1836,"imports":[{"path":"app/javascript/meta.js","kind":"import-statement","original":"../meta"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"../state"},{"path":"app/javascript/events.js","kind":"import-statement","original":"../events"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"../lifecycle"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"../urls"},{"path":"app/javascript/renderer.js","kind":"import-statement","original":"../renderer"},{"path":"","kind":"import-statement","external":true}],"format":"esm"},"app/javascript/drivers/index.js":{"bytes":2044,"imports":[{"path":"app/javascript/elements.js","kind":"import-statement","original":"../elements"},{"path":"app/javascript/drivers/form.js","kind":"import-statement","original":"./form"},{"path":"app/javascript/drivers/frame.js","kind":"import-statement","original":"./frame"},{"path":"app/javascript/drivers/method.js","kind":"import-statement","original":"./method"},{"path":"app/javascript/drivers/window.js","kind":"import-statement","original":"./window"}],"format":"esm"},"app/javascript/logger.js":{"bytes":729,"imports":[{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"}],"format":"esm"},"app/javascript/uuids.js":{"bytes":202,"imports":[],"format":"esm"},"app/javascript/index.js":{"bytes":3731,"imports":[{"path":"app/javascript/turbo.js","kind":"import-statement","original":"./turbo"},{"path":"app/javascript/schema.js","kind":"import-statement","original":"./schema"},{"path":"app/javascript/events.js","kind":"import-statement","original":"./events"},{"path":"app/javascript/activity.js","kind":"import-statement","original":"./activity"},{"path":"app/javascript/confirmation.js","kind":"import-statement","original":"./confirmation"},{"path":"app/javascript/delegates.js","kind":"import-statement","original":"./delegates"},{"path":"app/javascript/drivers/index.js","kind":"import-statement","original":"./drivers"},{"path":"app/javascript/meta.js","kind":"import-statement","original":"./meta"},{"path":"app/javascript/elements.js","kind":"import-statement","original":"./elements"},{"path":"app/javascript/lifecycle.js","kind":"import-statement","original":"./lifecycle"},{"path":"app/javascript/logger.js","kind":"import-statement","original":"./logger"},{"path":"app/javascript/state/index.js","kind":"import-statement","original":"./state"},{"path":"app/javascript/urls.js","kind":"import-statement","original":"./urls"},{"path":"app/javascript/uuids.js","kind":"import-statement","original":"./uuids"},{"path":"","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/commands.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":36739},"app/assets/builds/@turbo-boost/commands.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"app/javascript/meta.js":{"bytesInOutput":359},"app/javascript/events.js":{"bytesInOutput":500},"app/javascript/state/observable.js":{"bytesInOutput":405},"app/javascript/state/index.js":{"bytesInOutput":587},"app/javascript/renderer.js":{"bytesInOutput":263},"app/javascript/activity.js":{"bytesInOutput":173},"app/javascript/lifecycle.js":{"bytesInOutput":294},"app/javascript/turbo.js":{"bytesInOutput":889},"app/javascript/schema.js":{"bytesInOutput":166},"app/javascript/confirmation.js":{"bytesInOutput":424},"app/javascript/delegates.js":{"bytesInOutput":473},"app/javascript/elements.js":{"bytesInOutput":782},"app/javascript/drivers/form.js":{"bytesInOutput":246},"app/javascript/urls.js":{"bytesInOutput":166},"app/javascript/drivers/frame.js":{"bytesInOutput":96},"app/javascript/drivers/method.js":{"bytesInOutput":130},"app/javascript/drivers/window.js":{"bytesInOutput":1146},"app/javascript/drivers/index.js":{"bytesInOutput":991},"app/javascript/logger.js":{"bytesInOutput":399},"app/javascript/uuids.js":{"bytesInOutput":159},"app/javascript/index.js":{"bytesInOutput":1746}},"bytes":10891}}} \ No newline at end of file diff --git a/app/controllers/concerns/turbo_boost/commands/controller.rb b/app/controllers/concerns/turbo_boost/commands/controller.rb index 9a518871..e9037c13 100644 --- a/app/controllers/concerns/turbo_boost/commands/controller.rb +++ b/app/controllers/concerns/turbo_boost/commands/controller.rb @@ -5,7 +5,7 @@ module TurboBoost::Commands::Controller module ClassMethods def turbo_boost_state(&block) - TurboBoost::State::Manager.add_state_override_block name, block + TurboBoost::Commands::State.assign_resolver(&block) end end diff --git a/app/javascript/index.js b/app/javascript/index.js index 92a4d012..206f5c7a 100644 --- a/app/javascript/index.js +++ b/app/javascript/index.js @@ -21,10 +21,8 @@ function buildCommandPayload(id, element) { elementAttributes: elements.buildAttributePayload(element), startedAt: Date.now(), token: meta.token, // authenticity token - state: { - delta: meta.delta, // client side state changes (optimistic updates) - server: meta.server // server side state when the last command performed - } + signedState: meta.signedState, // server side state + state: state.changed // client side state (optimistic updates) } } @@ -103,8 +101,8 @@ self.TurboBoost = { return state.current }, - get stateDelta() { - return state.delta + get stateChanges() { + return state.changed } } diff --git a/app/javascript/meta.js b/app/javascript/meta.js index 9c74b0dd..3ee2b3a4 100644 --- a/app/javascript/meta.js +++ b/app/javascript/meta.js @@ -17,27 +17,14 @@ class Meta { return (this.element.dataset.busy = !!value) } - // mutable and optimistic client side state - get client() { - return JSON.parse(this.element.dataset.client) + // mutable state representation for use on the client + get state() { + return this.element.dataset.state } - set client(value = {}) { - return (this.element.dataset.client = JSON.stringify(value)) - } - - // mutable and optimistic client side state - get delta() { - return this.element.dataset.delta ? JSON.parse(this.element.dataset.delta) : {} - } - - set delta(value = {}) { - return (this.element.dataset.delta = JSON.stringify(value)) - } - - // immutable server side state - from the last command - get server() { - return this.element.dataset.server + // signed and immutable server state determined by the last command + get signedState() { + return this.element.dataset.signedState } } diff --git a/app/javascript/state/index.js b/app/javascript/state/index.js index eae39eb8..16d48069 100644 --- a/app/javascript/state/index.js +++ b/app/javascript/state/index.js @@ -7,7 +7,7 @@ let loadStateTimeout function loadState() { if (!meta.element) return loadStateLater() - const json = JSON.parse(meta.element.dataset.client) + const json = JSON.parse(meta.element.dataset.state) initialState = { ...json } currentState = observable(json) changedState = {} @@ -32,21 +32,22 @@ addEventListener('turbo:frame-load', loadStateLater) addEventListener(commandEvents.success, loadStateLater) addEventListener(stateEvents.stateChange, event => { - changedState = {} for (const [key, value] of Object.entries(currentState)) if (initialState[key] !== value) changedState[key] = value - meta.client = currentState - meta.delta = changedState }) export default { events: stateEvents, + get initial() { + return { ...initialState } + }, + get current() { return currentState }, - get delta() { - return changedState + get changed() { + return { ...changedState } } } diff --git a/docker-compose.yml b/docker-compose.yml index 92b1c23b..8da2582d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,7 +23,6 @@ x-default-app: &default_app - primary volumes: - .:/app - - ../universalid:/universalid - external:/mnt/external services: diff --git a/lib/turbo_boost/commands/controller_pack.rb b/lib/turbo_boost/commands/controller_pack.rb index 134da579..d4d07f02 100644 --- a/lib/turbo_boost/commands/controller_pack.rb +++ b/lib/turbo_boost/commands/controller_pack.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require_relative "../state" require_relative "runner" class TurboBoost::Commands::ControllerPack diff --git a/lib/turbo_boost/commands/engine.rb b/lib/turbo_boost/commands/engine.rb index dbda7bb6..c8be02ba 100644 --- a/lib/turbo_boost/commands/engine.rb +++ b/lib/turbo_boost/commands/engine.rb @@ -5,7 +5,6 @@ require "universalid" require_relative "version" require_relative "http_status_codes" -require_relative "../errors" require_relative "errors" require_relative "patches" require_relative "command" diff --git a/lib/turbo_boost/commands/errors.rb b/lib/turbo_boost/commands/errors.rb index b742c88e..ec18412a 100644 --- a/lib/turbo_boost/commands/errors.rb +++ b/lib/turbo_boost/commands/errors.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module TurboBoost::Commands + class InvalidTokenError < StandardError; end + class InvalidClassError < StandardError; end class InvalidMethodError < StandardError; end diff --git a/lib/turbo_boost/commands/runner.rb b/lib/turbo_boost/commands/runner.rb index a454d742..40681808 100644 --- a/lib/turbo_boost/commands/runner.rb +++ b/lib/turbo_boost/commands/runner.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative "sanitizer" +require_relative "state" class TurboBoost::Commands::Runner SUPPORTED_MEDIA_TYPES = { @@ -23,8 +24,8 @@ def meta_tag content: masked_token, # A signed token that can be used to verify command invocation data: { busy: false, # Indicates if a Command is active - client: state.to_json, # JSON that represents the state (mutable client-side) - server: state.to_sgid_param # SignedGlobalID that represents the state (immutable client-side) + state: state.to_json, # JSON that represents the current state + signed_state: state.to_sgid_param # Signed value that represents the current state (restored when commands are invoked) } } controller.view_context.tag("meta", options).html_safe @@ -32,9 +33,9 @@ def meta_tag def state @state ||= begin - sgid = command_params.dig(:state, :server) - value = TurboBoost::State.from_sgid_param(sgid) if sgid - value || TurboBoost::State.new + sgid = command_params[:signed_state] + value = TurboBoost::Commands::State.from_sgid_param(sgid) if sgid + value || TurboBoost::Commands::State.new end end @@ -59,7 +60,7 @@ def command_valid? # validate csrf token unless valid_client_token? - raise TurboBoost::InvalidTokenError, + raise TurboBoost::Commands::InvalidTokenError, "Token mismatch! The token: #{client_token}` does not match the expected value of `#{server_token}`." end @@ -222,12 +223,12 @@ def client_token end def valid_client_token? - return true # TODO: revisit this - return true unless Rails.configuration.turbo_boost_commands.validate_client_token - return false unless client_token.present? - return false unless message_verifier.valid_message?(client_token) - unmasked_client_token = message_verifier.verify(client_token) - unmasked_client_token == server_token + # return true unless Rails.configuration.turbo_boost_commands.validate_client_token + # return false unless client_token.present? + # return false unless message_verifier.valid_message?(client_token) + # unmasked_client_token = message_verifier.verify(client_token) + # unmasked_client_token == server_token + true # TODO: revisit this end def should_redirect? diff --git a/lib/turbo_boost/state.rb b/lib/turbo_boost/commands/state.rb similarity index 69% rename from lib/turbo_boost/state.rb rename to lib/turbo_boost/commands/state.rb index df1eb2d8..9937155d 100644 --- a/lib/turbo_boost/state.rb +++ b/lib/turbo_boost/commands/state.rb @@ -1,10 +1,18 @@ # frozen_string_literal: true -class TurboBoost::State +class TurboBoost::Commands::State class << self def from_sgid_param(sgid) new URI::UID.from_sgid(sgid, for: name)&.decode end + + def assign_resolver(&block) + @resolver = block + end + + def resolver + @resolver || ->(*_) {} + end end def initialize(store = nil) @@ -14,6 +22,18 @@ def initialize(store = nil) delegate_missing_to :store + def cache_key + "TurboBoost::Commands::State/#{Digest::SHA2.base64digest(to_json)}" + end + + def [](...) + store.read(...) + end + + def []=(...) + store.write(...) + end + def to_h store.cleanup data.each_with_object(HashWithIndifferentAccess.new) do |(key, entry), memo| diff --git a/lib/turbo_boost/errors.rb b/lib/turbo_boost/errors.rb deleted file mode 100644 index f0562af1..00000000 --- a/lib/turbo_boost/errors.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -module TurboBoost - class InvalidTokenError < StandardError - end -end diff --git a/lib/turbo_boost/state/errors.rb b/lib/turbo_boost/state/errors.rb deleted file mode 100644 index dd1bdc12..00000000 --- a/lib/turbo_boost/state/errors.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -class TurboBoost::State - # class DeserializationError < StandardError - # end -end diff --git a/lib/turbo_boost/state/manager.rb b/lib/turbo_boost/state/manager.rb deleted file mode 100644 index 45a1dbe5..00000000 --- a/lib/turbo_boost/state/manager.rb +++ /dev/null @@ -1,134 +0,0 @@ -# frozen_string_literal: true - -# require_relative "../state" -# require_relative "provisional_state" - -# Class used to hold ephemeral state related to the rendered UI. -# -# Examples: -# -# - Sidebar open/closed state -# - Tree view open/closed state -# - Accordion collapsed/expanded state -# - Customized layout / presentation -# - Applied data filters -# - Number of data rows to display etc. -# -class TurboBoost::State::Manager - # include ActiveModel::Dirty - - # class << self - # def state_override_blocks - # @state_overrides ||= {} - # end - - # def add_state_override_block(controller_name, block) - # state_override_blocks[controller_name] = block - # end - - # def state_override_block(controller) - # return nil if state_override_blocks.blank? - # ancestor = controller.class.ancestors.find { |a| state_override_blocks[a.name] } - # state_override_blocks[ancestor.name] - # end - # end - - # attr_reader :state - # attr_reader :controller, :header_data, :server_data - - ## For ActiveModel::Dirty tracking - # define_attribute_methods :state - - # def initialize(controller) - # @controller = controller - - # begin - # @state = TurboBoost::State.new - # rescue => error - # Rails.logger.error "Failed to construct TurboBoost::State! #{error.message}" - # @state = TurboBoost::State.new - # end - - ## State the server used to render the page last time - - ## State managed by the server on the backend (redis cache etc.) - ## SEE: `TurboBoost::State::Manager.state_override_block` - # server_state_hash = {} - - ## State the client expects... related to optimistic UI updates - ## i.e. Changes made on the client before making this request - # header_state_hash = {} - - ## Apply server state overrides (i.e. state stored in databases like Redis, Postgres, etc...) - # if TurboBoost::Commands.config.apply_server_state_overrides - # begin - # state_override_block = self.class.state_override_block(controller) - # if state_override_block - # server_state_hash = controller.instance_eval(&state_override_block).with_indifferent_access - # server_state_hash.each { |key, val| self[key] = val } - # end - # rescue => error - # Rails.logger.error "Failed to apply `state_override_block` configured in #{controller.class.name} to TurboBoost::State! #{error.message}" - # end - # end - - ## Apply client state overrides (i.e. optimistic state) - ## NOTE: Client state HTTP headers are only sent if/when state has changed on the client (only the changes are sent). - ## This prevents race conditions (state mismatch) caused when frame and XHR requests emit immediately - ## before the has been updated with the latest state from the server. - # if TurboBoost::Commands.config.apply_client_state_overrides - # begin - # header_state_hash = TurboBoost::State.deserialize_base64(header).with_indifferent_access - # header_state_hash.each { |key, val| self[key] = val } - # rescue => error - # Rails.logger.error "Failed to apply client state from HTTP headers to TurboBoost::State! #{error.message}" - # end - # end - - # @header_data = header_state_hash - # @server_data = server_state_hash - # rescue => error - # Rails.logger.error "Failed to construct TurboBoost::State! #{error.message}" - # ensure - # @state ||= TurboBoost::State.new - # end - - # delegate :cache_key, to: :state - - # def [](*keys, default: nil) - # state.read(*keys, default: default) - # end - - # def []=(*keys, value) - # state_will_change! if value != self[*keys] - # value.nil? ? state.delete(*keys) : state.write(*keys, value) - # end - - # def provisional_state - # @provisional_state ||= TurboBoost::State::ProvisionalState.new(self) - # end - - # alias_method :now, :provisional_state - - # def clear - # provisional_state.clear - # state.clear - # end - - # def payload - # provisional_state.clear - # state.shrink! - # state.payload - # end - - # private - - # def headers - # controller.request.headers.select { |(key, _)| key.match?(/TURBOBOOST_STATE/i) }.sort - # end - - ## State that exists on the client. - # def header - # headers.map(&:last).join - # end -end diff --git a/lib/turbo_boost/state/provisional_state.rb b/lib/turbo_boost/state/provisional_state.rb deleted file mode 100644 index c562a261..00000000 --- a/lib/turbo_boost/state/provisional_state.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require_relative "../state" - -class TurboBoost::State::ProvisionalState - # def initialize(state_manager) - # @state_manager = state_manager - # @keys = Set.new - # end - - # attr_reader :keys - - # def [](*keys, default: nil) - # state_manager[*keys, default: default] - # end - - # def []=(*keys, value) - # key = TurboBoost::State.key_for(*keys) - # value.nil? ? self.keys.delete(key) : self.keys.add(key) - # state_manager[key] = value - # end - - # def clear - # keys.each { |key| state_manager[key] = nil } - # keys.clear - # end - - # private - - # attr_reader :state_manager -end diff --git a/test/dummy/config/importmap.rb b/test/dummy/config/importmap.rb index 7408ead8..47125074 100644 --- a/test/dummy/config/importmap.rb +++ b/test/dummy/config/importmap.rb @@ -9,8 +9,8 @@ FileUtils.ln_s target, link, force: true, verbose: true unless File.exist?(link) pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:@hotwired/stimulus@3.2.2/dist/stimulus.js" -pin "@hotwired/turbo", to: "https://ga.jspm.io/npm:@hotwired/turbo@7.3.0/dist/turbo.es2017-esm.js" -pin "@hotwired/turbo-rails", to: "https://ga.jspm.io/npm:@hotwired/turbo-rails@7.3.0/app/javascript/turbo/index.js" +pin "@hotwired/turbo", to: "https://ga.jspm.io/npm:@hotwired/turbo@8.0.2/dist/turbo.es2017-esm.js" +pin "@hotwired/turbo-rails", to: "https://ga.jspm.io/npm:@hotwired/turbo-rails@8.0.2/app/javascript/turbo/index.js" pin "@rails/actioncable/src", to: "https://ga.jspm.io/npm:@rails/actioncable@7.1.3/src/index.js" pin "@turbo-boost/streams", to: "https://ga.jspm.io/npm:@turbo-boost/streams@0.0.8/app/assets/builds/@turbo-boost/streams.js" pin "debounced", to: "https://ga.jspm.io/npm:debounced@0.0.5/src/index.js" diff --git a/test/state_test.rb b/test/state_test.rb index 657aa29c..309bc374 100644 --- a/test/state_test.rb +++ b/test/state_test.rb @@ -4,7 +4,7 @@ class StateTest < ActiveSupport::TestCase test "new with defaults" do - state = TurboBoost::State.new + state = TurboBoost::Commands::State.new assert_respond_to state, :clear assert_respond_to state, :decrement assert_respond_to state, :fetch @@ -14,7 +14,7 @@ class StateTest < ActiveSupport::TestCase end test "new with expiration" do - state = TurboBoost::State.new(ActiveSupport::Cache::MemoryStore.new(expires_in: 1.second)) + state = TurboBoost::Commands::State.new(ActiveSupport::Cache::MemoryStore.new(expires_in: 1.second)) state.write :example, "value" assert_equal "value", state.read(:example) sleep 1 @@ -22,25 +22,31 @@ class StateTest < ActiveSupport::TestCase end test "new with size" do - state = TurboBoost::State.new(ActiveSupport::Cache::MemoryStore.new(size: 4.kilobytes)) + state = TurboBoost::Commands::State.new(ActiveSupport::Cache::MemoryStore.new(size: 4.kilobytes)) state.write :example, "0" * 4097.bytes assert_nil state.read(:example) assert_empty state.to_h end test "fetch" do - state = TurboBoost::State.new + state = TurboBoost::Commands::State.new assert_equal "value", state.fetch(:example) { "value" } end test "read and write" do - state = TurboBoost::State.new + state = TurboBoost::Commands::State.new state.write :example, "value" assert_equal "value", state.read(:example) end + test "read [] and write []= " do + state = TurboBoost::Commands::State.new + state[:example] = "value" + assert_equal "value", state[:example] + end + test "read and write with expiration" do - state = TurboBoost::State.new + state = TurboBoost::Commands::State.new state.write :example, "value", expires_in: 1.second assert_equal "value", state.read(:example) sleep 1 @@ -49,17 +55,17 @@ class StateTest < ActiveSupport::TestCase end test "to_h" do - state = TurboBoost::State.new + state = TurboBoost::Commands::State.new state.write :example, "value" expected = {"example" => "value"} assert_equal expected, state.to_h end - test "to_sgid and from_sgid" do - state = TurboBoost::State.new + test "to_sgid_param and from_sgid_param" do + state = TurboBoost::Commands::State.new state.write :example, "value" sgid = state.to_sgid_param - restored = TurboBoost::State.from_sgid_param(sgid) + restored = TurboBoost::Commands::State.from_sgid_param(sgid) assert_equal "value", restored.read(:example) end end diff --git a/test/system/basic_commands/turbo_boost_setup_test.rb b/test/system/basic_commands/turbo_boost_setup_test.rb index fee7f932..99f86753 100644 --- a/test/system/basic_commands/turbo_boost_setup_test.rb +++ b/test/system/basic_commands/turbo_boost_setup_test.rb @@ -24,7 +24,7 @@ class TurboBoosSetupTest < ApplicationSystemTestCase page.goto basic_command_url meta_element = page.wait_for_selector("meta#turbo-boost", state: "attached") - assert_equal "{}", meta_element["data-client"] + assert_equal "{}", meta_element["data-state"] assert_equal 0, js("Object.keys(TurboBoost.state).length") assert_equal 0, js("Object.values(TurboBoost.state).length") @@ -32,12 +32,6 @@ class TurboBoosSetupTest < ApplicationSystemTestCase js("TurboBoost.state.example = 'value'") assert js("TurboBoost.state.test") assert_equal "value", js("TurboBoost.state.example") - assert_equal "{\"test\":true,\"example\":\"value\"}", meta_element["data-delta"] - - js("TurboBoost.state.list = [1,2,3]") - assert_equal "{\"test\":true,\"example\":\"value\",\"list\":[1,2,3]}", meta_element["data-delta"] - - js("TurboBoost.state.obj = {a: true, b: false, c: 'value'}") - assert_equal "{\"test\":true,\"example\":\"value\",\"list\":[1,2,3],\"obj\":{\"a\":true,\"b\":false,\"c\":\"value\"}}", meta_element["data-delta"] + assert_equal "value", js("TurboBoost.stateChanges.example") end end diff --git a/turbo_boost-commands.gemspec b/turbo_boost-commands.gemspec index 0ab7ede1..3a1c160c 100644 --- a/turbo_boost-commands.gemspec +++ b/turbo_boost-commands.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_dependency "rails", ">= 6.1" s.add_dependency "turbo-rails", ">= 1.1" s.add_dependency "turbo_boost-streams", ">= 0.0.8" - s.add_dependency "universalid", ">= 0.1.6" + s.add_dependency "universalid", ">= 0.1.7" s.add_development_dependency "capybara" s.add_development_dependency "capybara-playwright-driver"