diff --git a/.npmrc b/.npmrc index 3367ea6..31b9c8b 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,3 @@ registry=https://registry.npmjs.org/ save-exact=true -package-lock=false +package-lock=true diff --git a/README.md b/README.md index dd37e1f..d5990ce 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ +# ReBars + > A simple, modern approach to Obvervables and DOM re-rendering and patching. -## [Documentation](https://dperrymorrow.github.io/re-bars) | [Examples](https://dperrymorrow.github.io/re-bars#example-simple) +## [Documentation](https://dperrymorrow.github.io/re-bars) | [Examples](https://dperrymorrow.github.io/re-bars/examples/advanced) - [ReBars Introduction](#rebars) - [A ReBars Application](#a-rebars-application) @@ -15,9 +17,10 @@ - [Partials](#partials) - [ReBars Helpers](#rebars-built-in-helpers) - [watch (re-rendering)](#the-watch-helper) - - [concat (string building)](#the-concat-helper) - [on (event handling)](#the-on-helper) - - [ref (element reference)](#the-ref-helper) + - [bind (data binding)](#the-bind-helper) + - [ref ($el reference)](#the-ref-helper) + - [key (pointer reference)](#the-key-helper) --- @@ -43,12 +46,14 @@ ReBars started with the idea of so what do I _actually_ need from a Javascript f ReBars re-renders tiny pieces of your application on change. You are in control of what re-renders and when. There is no... - ❌ Virtual DOM -- ❌ JSX or anything else to pre-compile +- ❌ JSX or others that need pre-built to JS - ❌ DOM diffing and patching +- ❌ Single File Components +- ❌ CSS pre-processing and extracting **Your** code simply runs on **your** app. -> In fact there is zero DOM diffing / checking of any kind in ReBars. Marked elements are simply re-rendered when correlating data changes. +> In fact the only time ReBars will compare any DOM is when an Array is being patched. All other times ReBars simply calls the Handlebars method again, and replaces the HTML. ReBars keeps your DOM in sync with your data using [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and gets out of your way. You can get back to just writing Javascript. @@ -469,15 +474,19 @@ ReBars consists of a few very powerful Handlebars helpers. Of course you can add The watch helper tells ReBars to re-render this block on change of the item you pass in as the second parameter. - Watch allows you to re-render a block of your template on change. Watch takes an _optional_ arguments of what properties to watch. The arguments can be string or a regular expression. You may also as many as you like. When any change, the block will re-render. -In our explanation below, we will be referring to this data set. +```handlebars +{{#watch}} + My name is {{ name.first }} {{ name.last }}. +{{/watch}} +``` ```javascript { data: { + open: false, hobby: "running", name: { first: "David", @@ -490,21 +499,30 @@ In our explanation below, we will be referring to this data set. } } ``` -```html -{{#watch}} - My name is {{ name.first }} {{ name.last }}. -{{/watch}} -``` The above omits the what to watch. In this situation, ReBars will pre-render the block, and captures any references used. It would evaluate to the same as. - -```html +```handlebars {{#watch "name.first" "name.last" }} ``` -> If you are unsure what to watch, ReBars traces out changes to the console when you pass `trace: true` to your application. +### Automatic Watch pitfalls + +Sometimes automatically inferring what to watch will not have the desired effect. + +```handlebars +{{#watch}} + My name is: {{ name.first }} {{ name.last }} + {{#if open }} + {{ hobby }} + {{/if}} +{{/watch}} +``` + +In the example above, only `name.first` `name.last` will be watched. This is because open was false and hobby was not referenced. When in doubt, be specific. + +> If you are unsure what to watch, ReBars traces out changes to the console when you pass `trace: true` to your application. It's best to be explicit when telling ReBars what to watch. | Argument Example | re-renders when | | - | - | @@ -531,46 +549,16 @@ export default { {{#watch "name" tag="h3"}} {{ name }} {{/watch}} - - + `, data: { name: "David", }, - methods: { - saveName({ event }) { - this.name = event.target.value; - }, - }, }; ``` -## The Concat Helper - -Sometimes you need to piece together something that is a combination of a dynamic value, and a static. Thats where this simple little helper comes in handy. - -In this example we are looking to not re-render the entire Array on change of any of it's items. So we use the concat helper as a [sub expression](https://handlebarsjs.com/guide/expressions.html#subexpressions) - -> Notice the `()` around the sub expression. You will get a syntax error without them! - -```handlebars -{{#watch "todos.length" tag="ul"}} - {{#each todos as | todo | }} - {{#watch (concat "todos." @index "(.*)") tag="li" }} - {{ todo.name }} - {{/watch}} - {{/each}} -{{/watch}} -``` - -The above results in the equivalent of - -```handlebars -{{#watch "todos.1(.*)" }} -``` - ## The on helper This allows you to bind your component's methods to events in your template. The method will be called with the first param an Object as described [above](#methods) and any additional params that are passed to the helper. @@ -592,12 +580,54 @@ methods: { > Remember Handlebars requires params to be first, and then `key="val"` arguments second -You can also call multiple events on one invocation of the on helpers. For example. +You can also call multiple events on one use of the on helper. For example. ```html ``` +## The Bind Helper + +The bind helper is very simimar to the [on helper](#the-on-helper) with one exception. It saves you from having to write a method in your app when all you want to do is set a value. + +For example: + +```handlebars + +``` + +```javascript +data: { + name: { + first: "David", + last: "Morrow" + } +} +``` + +As opposed to: + +```handlebars + +``` + +```javascript +data: { + name: { + first: "David", + last: "Morrow" + } +}, + +methods: { + updateLastName({ event }) { + this.name.last = event.target.value; + } +} +``` + +On each input event of the text input, the last name will be updated to the input's current value. This is merely a convienance, and could be accomplished by defining a method. But is useful in many common cases. + ## The ref helper The ref helper gives you an alias to a DOM element in your template. The `$refs` method can be accessed in the context passed like other items in the context. @@ -617,3 +647,46 @@ methods: { } ``` +## The Key Helper + +This simple little helper marks individual items with a unique identifier you provide. The main use for this is when you have a `{{#watch}}` around an Array in your data. + +```handlebars +{{#watch "friends" }} + +{{/watch}} +``` + +```javascript +{ + data: { + friends: [ + { id: 1, name: "Fred" }, + { id: 2, name: "Mike" }, + ] + } +} +``` + +In the above example, on each change of any item in your todos, the entire UL block would re-render. This is not ideal, and ReBars is smart enough to determine which elements need changed. + +Alternativly: + +```handlebars +{{#watch "friends" }} + +{{/watch}} +``` + +Now when the Array friends is updated, ReBars will have a unique identifier to compare which items have changed and only update those items. + +> Allthough it may work initially, using [@index](https://handlebarsjs.com/api-reference/data-variables.html#index) as your key value is not encouraged. Should you sort or reasign your Array, those indexes will no longer be a valid identifier for that item in the Array. + diff --git a/dist/re-bars.esm.js b/dist/re-bars.esm.js index 3a9db3c..ad5fa51 100644 --- a/dist/re-bars.esm.js +++ b/dist/re-bars.esm.js @@ -37,7 +37,7 @@ var Dom = { restoreState($target, activeRef) { if (!activeRef) return; - const $input = this.findRef($target, activeRef.ref); + const $input = this.findAttr(attrs.ref, activeRef.ref, $target); if (!$input) return; $input.focus(); @@ -66,15 +66,11 @@ var Dom = { // use this in place of all the others that are repeated eventually... findAttr(attr, val, $target = null) { const $container = $target || document; - if ($container.getAttribute(attr) === val) return $container; + // check top level + if ($target && $target.getAttribute(attr) === val) return $target; return $container.querySelector(`[${attr}="${val}"]`); }, - findRef: ($target, ref) => { - if ($target.getAttribute(attrs.ref) === ref) return $target; - return $target.querySelector(`[${attrs.ref}="${ref}"]`); - }, - findMethod: id => document.querySelector(`[${attrs.method}="${id}"]`), findWatcher: id => document.querySelector(`[${attrs.watch}="${id}"]`), isTextNode: $el => $el.nodeType === Node.TEXT_NODE, @@ -232,17 +228,17 @@ var Helpers = { instance.registerHelper("key", name => new instance.SafeString(`${attrs$1.key}="${name}"`)); instance.registerHelper("ref", name => new instance.SafeString(`${attrs$1.ref}="${name}"`)); - instance.registerHelper("concat", function(...args) { - args.pop(); - return args.join(""); - }); - instance.registerHelper("onlyIf", function(...args) { args.pop(); const [condition, string] = args; return new instance.SafeString(condition ? string : ""); }); + instance.registerHelper("concat", function(...args) { + args.pop(); + return new instance.SafeString(args.join("")); + }); + instance.registerHelper("on", function(...args) { const { hash } = args.pop(); const id = Utils.randomId(); @@ -273,6 +269,7 @@ var Helpers = { instance.registerHelper("bind", function(...args) { const { hash } = args.pop(); + const [forceValue] = args; const tplScope = this; const id = Utils.randomId(); @@ -284,8 +281,11 @@ var Helpers = { Object.entries(hash).forEach(([eventType, path]) => { function handler(event) { + let value = event.target.value; + value = value === "" ? null : value; + try { - Utils.setPath(tplScope, path, event.target.value || null); + Utils.setPath(tplScope, path, forceValue || value); } catch (err) { instance.log(3, `ReBars: could not set path ${path}`, $el); } @@ -460,18 +460,20 @@ const ReBars = { Handlebars = window ? window.Handlebars : null, trace = false, }) { - const instance = Handlebars.create(); - - const store = { renders: {}, handlers: {} }; if (!Handlebars) throw new Error("ReBars: needs Handlebars in order to run"); + const instance = Handlebars.create(); + const store = { renders: {}, handlers: {} }; Config.setTrace(trace); return { store, instance, async render(selector) { - const $app = document.querySelector(selector); + // takes an element or a selector + const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector); + + if (!$app) throw new Error(`ReBars: document.querySelector("${selector}") could not be found on the document`); // have to make sure they are resolved first await Promise.all(Object.values(partials)); @@ -482,13 +484,10 @@ const ReBars = { // must be compiled after the partials const templateFn = instance.compile(template instanceof Promise ? await template : template); - if (!$app) - return instance.log(3, `ReBars: document.querySelector("${selector}") could not be found on the document`); - const scope = { $app, methods, - data, + data: typeof data === "function" ? data() : data, }; Utils.registerHelpers({ instance, helpers, scope }); @@ -510,6 +509,8 @@ const ReBars = { if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context); $app.innerHTML = templateFn(scope.data); if (hooks.afterRender) await hooks.afterRender.call(scope.data, context); + + return context; }, }; }, diff --git a/dist/re-bars.esm.min.js b/dist/re-bars.esm.min.js index 0f3bff5..a3255c5 100644 --- a/dist/re-bars.esm.min.js +++ b/dist/re-bars.esm.min.js @@ -1,2 +1,2 @@ -let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const r=this.findRef(e,t.ref);if(r){if(r.focus(),t.selectionStart){const e="TEXTAREA"===r.tagName?t.selectionStart:t.selectionStart+1;r.setSelectionRange(e,e)}r.scrollTop=t.scrollTop,r.scrollLeft=t.scrollLeft,t.style&&r.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return n.getAttribute(e)===t?n:n.querySelector(`[${e}="${t}"]`)},findRef:(e,t)=>e.getAttribute(r.ref)===t?e:e.querySelector(`[${r.ref}="${t}"]`),findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("concat",(function(...e){return e.pop(),e.join("")})),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),o=this,a=s.randomId();return n.handlers[a]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(a);t&&Object.entries(r).forEach(([r,c])=>{function i(r){try{s.setPath(o,c,r.target.value||null)}catch(r){e.log(3,`ReBars: could not set path ${c}`,t)}}n.handlers[a].push({$el:t,handler:i,eventType:r}),t.addEventListener(r,i)})}),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){const f=h.create(),m={renders:{},handlers:{}};if(!h)throw new Error("ReBars: needs Handlebars in order to run");return t.setTrace(u),{store:m,instance:f,async render(h){const u=document.querySelector(h);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r);if(!u)return f.log(3,`ReBars: document.querySelector("${h}") could not be found on the document`);const b={$app:u,methods:o,data:n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w)}}}};window&&(window.ReBars=window.ReBars||m);export default m; +let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const n=this.findAttr(r.ref,t.ref,e);if(n){if(n.focus(),t.selectionStart){const e="TEXTAREA"===n.tagName?t.selectionStart:t.selectionStart+1;n.setSelectionRange(e,e)}n.scrollTop=t.scrollTop,n.scrollLeft=t.scrollLeft,t.style&&n.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return r&&r.getAttribute(e)===t?r:n.querySelector(`[${e}="${t}"]`)},findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("concat",(function(...t){return t.pop(),new e.SafeString(t.join(""))})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),[o]=t,a=this,c=s.randomId();return n.handlers[c]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(c);t&&Object.entries(r).forEach(([r,i])=>{function d(r){let n=r.target.value;n=""===n?null:n;try{s.setPath(a,i,o||n)}catch(r){e.log(3,`ReBars: could not set path ${i}`,t)}}n.handlers[c].push({$el:t,handler:d,eventType:r}),t.addEventListener(r,d)})}),new e.SafeString(`${i.method}="${c}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){if(!h)throw new Error("ReBars: needs Handlebars in order to run");const f=h.create(),m={renders:{},handlers:{}};return t.setTrace(u),{store:m,instance:f,async render(h){const u=h.nodeType===Node.ELEMENT_NODE?h:document.querySelector(h);if(!u)throw new Error(`ReBars: document.querySelector("${h}") could not be found on the document`);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r),b={$app:u,methods:o,data:"function"==typeof n?n():n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);return l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w),w}}}};window&&(window.ReBars=window.ReBars||m);export default m; //# sourceMappingURL=re-bars.esm.min.js.map diff --git a/dist/re-bars.esm.min.js.gz b/dist/re-bars.esm.min.js.gz index 9531eb4..1d4f4b5 100644 Binary files a/dist/re-bars.esm.min.js.gz and b/dist/re-bars.esm.min.js.gz differ diff --git a/dist/re-bars.esm.min.js.map b/dist/re-bars.esm.min.js.map index 3ee01f6..c418ed3 100644 --- a/dist/re-bars.esm.min.js.map +++ b/dist/re-bars.esm.min.js.map @@ -1 +1 @@ -{"version":3,"file":"re-bars.esm.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/app.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findRef($target, activeRef.ref);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n if ($container.getAttribute(attr) === val) return $container;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findRef: ($target, ref) => {\n if ($target.getAttribute(attrs.ref) === ref) return $target;\n return $target.querySelector(`[${attrs.ref}=\"${ref}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return args.join(\"\");\n });\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n try {\n Utils.setPath(tplScope, path, event.target.value || null);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n const instance = Handlebars.create();\n\n const store = { renders: {}, handlers: {} };\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n const $app = document.querySelector(selector);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n if (!$app)\n return instance.log(3, `ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n const scope = {\n $app,\n methods,\n data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findRef","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","findAttr","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"re-bars.esm.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/index.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findAttr(attrs.ref, activeRef.ref, $target);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n // check top level\n if ($target && $target.getAttribute(attr) === val) return $target;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return new instance.SafeString(args.join(\"\"));\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const [forceValue] = args;\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n let value = event.target.value;\n value = value === \"\" ? null : value;\n\n try {\n Utils.setPath(tplScope, path, forceValue || value);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n const instance = Handlebars.create();\n const store = { renders: {}, handlers: {} };\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n // takes an element or a selector\n const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector);\n\n if (!$app) throw new Error(`ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n const scope = {\n $app,\n methods,\n data: typeof data === \"function\" ? data() : data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n\n return context;\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findAttr","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","forceValue","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"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"} \ No newline at end of file diff --git a/dist/re-bars.umd.js b/dist/re-bars.umd.js index 0760103..6614d0b 100644 --- a/dist/re-bars.umd.js +++ b/dist/re-bars.umd.js @@ -43,7 +43,7 @@ restoreState($target, activeRef) { if (!activeRef) return; - const $input = this.findRef($target, activeRef.ref); + const $input = this.findAttr(attrs.ref, activeRef.ref, $target); if (!$input) return; $input.focus(); @@ -72,15 +72,11 @@ // use this in place of all the others that are repeated eventually... findAttr(attr, val, $target = null) { const $container = $target || document; - if ($container.getAttribute(attr) === val) return $container; + // check top level + if ($target && $target.getAttribute(attr) === val) return $target; return $container.querySelector(`[${attr}="${val}"]`); }, - findRef: ($target, ref) => { - if ($target.getAttribute(attrs.ref) === ref) return $target; - return $target.querySelector(`[${attrs.ref}="${ref}"]`); - }, - findMethod: id => document.querySelector(`[${attrs.method}="${id}"]`), findWatcher: id => document.querySelector(`[${attrs.watch}="${id}"]`), isTextNode: $el => $el.nodeType === Node.TEXT_NODE, @@ -238,17 +234,17 @@ instance.registerHelper("key", name => new instance.SafeString(`${attrs$1.key}="${name}"`)); instance.registerHelper("ref", name => new instance.SafeString(`${attrs$1.ref}="${name}"`)); - instance.registerHelper("concat", function(...args) { - args.pop(); - return args.join(""); - }); - instance.registerHelper("onlyIf", function(...args) { args.pop(); const [condition, string] = args; return new instance.SafeString(condition ? string : ""); }); + instance.registerHelper("concat", function(...args) { + args.pop(); + return new instance.SafeString(args.join("")); + }); + instance.registerHelper("on", function(...args) { const { hash } = args.pop(); const id = Utils.randomId(); @@ -279,6 +275,7 @@ instance.registerHelper("bind", function(...args) { const { hash } = args.pop(); + const [forceValue] = args; const tplScope = this; const id = Utils.randomId(); @@ -290,8 +287,11 @@ Object.entries(hash).forEach(([eventType, path]) => { function handler(event) { + let value = event.target.value; + value = value === "" ? null : value; + try { - Utils.setPath(tplScope, path, event.target.value || null); + Utils.setPath(tplScope, path, forceValue || value); } catch (err) { instance.log(3, `ReBars: could not set path ${path}`, $el); } @@ -466,18 +466,20 @@ Handlebars = window ? window.Handlebars : null, trace = false, }) { - const instance = Handlebars.create(); - - const store = { renders: {}, handlers: {} }; if (!Handlebars) throw new Error("ReBars: needs Handlebars in order to run"); + const instance = Handlebars.create(); + const store = { renders: {}, handlers: {} }; Config.setTrace(trace); return { store, instance, async render(selector) { - const $app = document.querySelector(selector); + // takes an element or a selector + const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector); + + if (!$app) throw new Error(`ReBars: document.querySelector("${selector}") could not be found on the document`); // have to make sure they are resolved first await Promise.all(Object.values(partials)); @@ -488,13 +490,10 @@ // must be compiled after the partials const templateFn = instance.compile(template instanceof Promise ? await template : template); - if (!$app) - return instance.log(3, `ReBars: document.querySelector("${selector}") could not be found on the document`); - const scope = { $app, methods, - data, + data: typeof data === "function" ? data() : data, }; Utils.registerHelpers({ instance, helpers, scope }); @@ -516,6 +515,8 @@ if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context); $app.innerHTML = templateFn(scope.data); if (hooks.afterRender) await hooks.afterRender.call(scope.data, context); + + return context; }, }; }, diff --git a/dist/re-bars.umd.min.js b/dist/re-bars.umd.min.js index 2ba96dd..5175f75 100644 --- a/dist/re-bars.umd.min.js +++ b/dist/re-bars.umd.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).ReBars=t()}(this,(function(){"use strict";let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const r=this.findRef(e,t.ref);if(r){if(r.focus(),t.selectionStart){const e="TEXTAREA"===r.tagName?t.selectionStart:t.selectionStart+1;r.setSelectionRange(e,e)}r.scrollTop=t.scrollTop,r.scrollLeft=t.scrollLeft,t.style&&r.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return n.getAttribute(e)===t?n:n.querySelector(`[${e}="${t}"]`)},findRef:(e,t)=>e.getAttribute(r.ref)===t?e:e.querySelector(`[${r.ref}="${t}"]`),findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("concat",(function(...e){return e.pop(),e.join("")})),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),o=this,a=s.randomId();return n.handlers[a]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(a);t&&Object.entries(r).forEach(([r,c])=>{function i(r){try{s.setPath(o,c,r.target.value||null)}catch(r){e.log(3,`ReBars: could not set path ${c}`,t)}}n.handlers[a].push({$el:t,handler:i,eventType:r}),t.addEventListener(r,i)})}),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){const f=h.create(),m={renders:{},handlers:{}};if(!h)throw new Error("ReBars: needs Handlebars in order to run");return t.setTrace(u),{store:m,instance:f,async render(h){const u=document.querySelector(h);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r);if(!u)return f.log(3,`ReBars: document.querySelector("${h}") could not be found on the document`);const b={$app:u,methods:o,data:n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w)}}}};return window&&(window.ReBars=window.ReBars||m),m})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).ReBars=t()}(this,(function(){"use strict";let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const n=this.findAttr(r.ref,t.ref,e);if(n){if(n.focus(),t.selectionStart){const e="TEXTAREA"===n.tagName?t.selectionStart:t.selectionStart+1;n.setSelectionRange(e,e)}n.scrollTop=t.scrollTop,n.scrollLeft=t.scrollLeft,t.style&&n.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return r&&r.getAttribute(e)===t?r:n.querySelector(`[${e}="${t}"]`)},findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("concat",(function(...t){return t.pop(),new e.SafeString(t.join(""))})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),[o]=t,a=this,c=s.randomId();return n.handlers[c]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(c);t&&Object.entries(r).forEach(([r,i])=>{function d(r){let n=r.target.value;n=""===n?null:n;try{s.setPath(a,i,o||n)}catch(r){e.log(3,`ReBars: could not set path ${i}`,t)}}n.handlers[c].push({$el:t,handler:d,eventType:r}),t.addEventListener(r,d)})}),new e.SafeString(`${i.method}="${c}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){if(!h)throw new Error("ReBars: needs Handlebars in order to run");const f=h.create(),m={renders:{},handlers:{}};return t.setTrace(u),{store:m,instance:f,async render(h){const u=h.nodeType===Node.ELEMENT_NODE?h:document.querySelector(h);if(!u)throw new Error(`ReBars: document.querySelector("${h}") could not be found on the document`);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r),b={$app:u,methods:o,data:"function"==typeof n?n():n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);return l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w),w}}}};return window&&(window.ReBars=window.ReBars||m),m})); //# sourceMappingURL=re-bars.umd.min.js.map diff --git a/dist/re-bars.umd.min.js.gz b/dist/re-bars.umd.min.js.gz index 47d9386..6ff03b0 100644 Binary files a/dist/re-bars.umd.min.js.gz and b/dist/re-bars.umd.min.js.gz differ diff --git a/dist/re-bars.umd.min.js.map b/dist/re-bars.umd.min.js.map index 8b84c78..ca70084 100644 --- a/dist/re-bars.umd.min.js.map +++ b/dist/re-bars.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"re-bars.umd.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/app.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findRef($target, activeRef.ref);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n if ($container.getAttribute(attr) === val) return $container;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findRef: ($target, ref) => {\n if ($target.getAttribute(attrs.ref) === ref) return $target;\n return $target.querySelector(`[${attrs.ref}=\"${ref}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return args.join(\"\");\n });\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n try {\n Utils.setPath(tplScope, path, event.target.value || null);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n const instance = Handlebars.create();\n\n const store = { renders: {}, handlers: {} };\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n const $app = document.querySelector(selector);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n if (!$app)\n return instance.log(3, `ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n const scope = {\n $app,\n methods,\n data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findRef","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","findAttr","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"re-bars.umd.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/index.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findAttr(attrs.ref, activeRef.ref, $target);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n // check top level\n if ($target && $target.getAttribute(attr) === val) return $target;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return new instance.SafeString(args.join(\"\"));\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const [forceValue] = args;\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n let value = event.target.value;\n value = value === \"\" ? null : value;\n\n try {\n Utils.setPath(tplScope, path, forceValue || value);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n const instance = Handlebars.create();\n const store = { renders: {}, handlers: {} };\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n // takes an element or a selector\n const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector);\n\n if (!$app) throw new Error(`ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n const scope = {\n $app,\n methods,\n data: typeof data === \"function\" ? data() : data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n\n return context;\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findAttr","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","forceValue","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"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"} \ No newline at end of file diff --git a/docs/dist/re-bars.umd.min.js b/docs/dist/re-bars.umd.min.js index 2ba96dd..5175f75 100644 --- a/docs/dist/re-bars.umd.min.js +++ b/docs/dist/re-bars.umd.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).ReBars=t()}(this,(function(){"use strict";let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const r=this.findRef(e,t.ref);if(r){if(r.focus(),t.selectionStart){const e="TEXTAREA"===r.tagName?t.selectionStart:t.selectionStart+1;r.setSelectionRange(e,e)}r.scrollTop=t.scrollTop,r.scrollLeft=t.scrollLeft,t.style&&r.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return n.getAttribute(e)===t?n:n.querySelector(`[${e}="${t}"]`)},findRef:(e,t)=>e.getAttribute(r.ref)===t?e:e.querySelector(`[${r.ref}="${t}"]`),findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("concat",(function(...e){return e.pop(),e.join("")})),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),o=this,a=s.randomId();return n.handlers[a]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(a);t&&Object.entries(r).forEach(([r,c])=>{function i(r){try{s.setPath(o,c,r.target.value||null)}catch(r){e.log(3,`ReBars: could not set path ${c}`,t)}}n.handlers[a].push({$el:t,handler:i,eventType:r}),t.addEventListener(r,i)})}),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){const f=h.create(),m={renders:{},handlers:{}};if(!h)throw new Error("ReBars: needs Handlebars in order to run");return t.setTrace(u),{store:m,instance:f,async render(h){const u=document.querySelector(h);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r);if(!u)return f.log(3,`ReBars: document.querySelector("${h}") could not be found on the document`);const b={$app:u,methods:o,data:n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w)}}}};return window&&(window.ReBars=window.ReBars||m),m})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).ReBars=t()}(this,(function(){"use strict";let e=!1;var t={logLevel:()=>e?1:0,setTrace:t=>e=t,regex:{attrs:/rbs-(.*?)="(.*?)"/g,whitespace:/\s/g},attrs:{key:"rbs-key",watch:"rbs-watch",method:"rbs-method",ref:"rbs-ref"}};const{attrs:r}=t;var n={recordState(e){const t=document.activeElement,n=t.getAttribute(r.ref);return e.contains(t)&&n?{ref:n,style:t.getAttribute("style"),scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,selectionStart:t.selectionStart}:null},restoreState(e,t){if(!t)return;const n=this.findAttr(r.ref,t.ref,e);if(n){if(n.focus(),t.selectionStart){const e="TEXTAREA"===n.tagName?t.selectionStart:t.selectionStart+1;n.setSelectionRange(e,e)}n.scrollTop=t.scrollTop,n.scrollLeft=t.scrollLeft,t.style&&n.setAttribute("style",t.style)}},findRefs(e){const{ref:t}=r;return Array.from(e.querySelectorAll(`[${t}]`)).reduce((e,r)=>{const n=r.getAttribute(t),o=e[n];return e[n]=o?[o].concat(r):r,e},{})},findAttr(e,t,r=null){const n=r||document;return r&&r.getAttribute(e)===t?r:n.querySelector(`[${e}="${t}"]`)},findMethod:e=>document.querySelector(`[${r.method}="${e}"]`),findWatcher:e=>document.querySelector(`[${r.watch}="${e}"]`),isTextNode:e=>e.nodeType===Node.TEXT_NODE,propStr:e=>Object.entries(e).map(([e,t])=>"number"==typeof t?`${e}=${t}`:`${e}="${t}"`).join(" "),wrapWatcher(e,t,n){const{tag:o,...a}={tag:"span",...n};return`<${o} ${this.propStr(a)} ${t.length?"":"style='display:none;'"} ${r.watch}="${e}">${t}`},getShadow(e){const t=document.createElement("div");return t.innerHTML=e,t}};const{fetch:o}=window;let a=1;var s={dom:n,debounce(e,t=0,r=!1){let n=null;return function(){const o=r&&!n,a=()=>e.apply(this,arguments);clearTimeout(n),n=setTimeout(a,t),o&&a()}},loadTemplate:e=>o(e).then(e=>e.text()).catch(e=>{throw new Error(e)}),nextTick:()=>new Promise(e=>{setTimeout(e,0)}),setPath(e,t,r){const n=t.split("."),o=n.pop();return n.reduce((e,t)=>e[t],e)[o]=r,e},buildContext(e,{$app:t,data:r,methods:n}){const o={$app:t,$nextTick:this.nextTick,$refs:this.dom.findRefs.bind(null,t),rootData:r};return o.methods=this.bind(n,e,o),o},registerHelpers({instance:e,helpers:t,scope:r}){const n=this;Object.entries(t).forEach(([t,o])=>e.registerHelper(t,(function(...e){const t=n.buildContext(this,r);return o.call(this,t,...e)})))},bind:(e,t,...r)=>Object.keys(e).reduce((n,o)=>(n[o]=e[o].bind(t,...r),n),{}),shouldRender:(e,t)=>e.some(e=>t.some(t=>e.match(t))),randomId:()=>a++},c={create(e,t,r=!1){let n=[];const o=s.debounce(()=>{t(n),n=[]}),a=e=>{n.includes(e)||n.push(e),o(n)};const c=function t(n,o=[]){return new Proxy(n,{get:function(n,i){const d=Reflect.get(...arguments);return"function"==typeof d&&n.hasOwnProperty(i)?d.bind(c,s.buildContext(n,e)):d&&"object"==typeof d&&["Array","Object"].includes(d.constructor.name)?t(d,o.concat(i)):(r&&a(o.concat(i).join(".")),d)},set:function(e,t,r){const n=Reflect.set(...arguments),s=o.concat(t).join(".");return a(s),n},deleteProperty:function(e,t){const r=Reflect.deleteProperty(...arguments),n=o.concat(t).join(".");return a(n),r}})}(e.data);return c}};const{attrs:i}=t;var d={register({instance:e,template:r,store:n,scope:o}){e.registerHelper("key",t=>new e.SafeString(`${i.key}="${t}"`)),e.registerHelper("ref",t=>new e.SafeString(`${i.ref}="${t}"`)),e.registerHelper("onlyIf",(function(...t){t.pop();const[r,n]=t;return new e.SafeString(r?n:"")})),e.registerHelper("concat",(function(...t){return t.pop(),new e.SafeString(t.join(""))})),e.registerHelper("on",(function(...t){const{hash:r}=t.pop(),a=s.randomId(),c=this;return n.handlers[a]=[],s.nextTick().then((function(){const i=s.dom.findMethod(a);i&&Object.entries(r).forEach(([d,l])=>{l in o.methods||e.log(3,`ReBars: "${l}" is not a method.`,r,i);const h=e=>{const r=s.buildContext(c,o);r.event=e,r.methods[l](...t)};n.handlers[a].push({$el:i,handler:h,eventType:d}),i.addEventListener(d,h)})})),new e.SafeString(`${i.method}="${a}"`)})),e.registerHelper("bind",(function(...t){const{hash:r}=t.pop(),[o]=t,a=this,c=s.randomId();return n.handlers[c]=[],s.nextTick().then(()=>{const t=s.dom.findMethod(c);t&&Object.entries(r).forEach(([r,i])=>{function d(r){let n=r.target.value;n=""===n?null:n;try{s.setPath(a,i,o||n)}catch(r){e.log(3,`ReBars: could not set path ${i}`,t)}}n.handlers[c].push({$el:t,handler:d,eventType:r}),t.addEventListener(r,d)})}),new e.SafeString(`${i.method}="${c}"`)})),e.registerHelper("watch",(function(...r){const{fn:a,hash:i}=r.pop(),d=s.randomId(),l={path:r.filter(e=>"string"==typeof e),render:()=>a(this)};if(!r.length){const e=c.create({...o,data:this},e=>{l.path=e},!0);a(e)}return s.nextTick().then(()=>{const o=s.dom.findWatcher(d);o&&(n.renders[d]={...l,$el:o},r.forEach(t=>{"string"!=typeof t&&e.log(3,"ReBars: can only watch Strings",r,o)}),e.log(t.logLevel(),"ReBars: watching",l.path,o))}),s.dom.wrapWatcher(d,a(this),i)}))}};const{attrs:l,regex:h}=t;function u(e,t){const r=e.replace(h.attrs,""),n=t.replace(h.attrs,"");return s.dom.getShadow(r).isEqualNode(s.dom.getShadow(n))}var f={canPatch:e=>e.children.length&&e.children.length>1&&Array.from(e.children).every(e=>e.getAttribute(l.key)),hasChanged:(e,t)=>!u(e.innerHTML,t),compare({$target:e,html:r,instance:n,store:o}){const a=s.dom.getShadow(r),c=Array.from(a.children),i=t.logLevel();Array.from(e.children).forEach(e=>{"undefined"===e.getAttribute(l.key)&&n.log(3,"ReBars: key was undefined",e);const t=s.dom.findAttr(l.key,e.getAttribute(l.key),a);t?u(t.innerHTML,e.innerHTML)||(n.log(i,"ReBars: updating",e,t),e.replaceWith(t.cloneNode(!0))):(n.log(i,"ReBars: removing",e),e.remove())}),c.forEach((t,r)=>{s.dom.findAttr(l.key,t.getAttribute(l.key),e)||(n.log(i,"ReBars: adding",t),e.append(t.cloneNode(!0)))}),c.forEach((t,r)=>{const n=e.children[r];n.getAttribute(l.key)!==t.getAttribute(l.key)&&n.replaceWith(t.cloneNode(!0))})}},p={paths({changed:e,store:r,instance:n}){Object.entries(r.renders).filter(([t,r])=>s.shouldRender(e,r.path)&&s.dom.findWatcher(t)).forEach(([e,o])=>{const a=s.dom.findWatcher(e);if(!a)return;const c=o.render(),i=s.dom.recordState(a);if(f.hasChanged(a,c)){if(f.canPatch(a))return n.log(t.logLevel(),"ReBars: patching",o.path,a),f.compare({$target:a,html:c,instance:n,store:r}),void s.dom.restoreState(a,i);a.style.display=""===c?"none":"",a.innerHTML=c,s.dom.restoreState(a,i),n.log(t.logLevel(),"ReBars: re-render",o.path,a)}})}},g={start(e,{renders:r,handlers:n}){const o=new MutationObserver(([e])=>{e.removedNodes.forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const o=e.getAttribute(t.attrs.watch),a=e.getAttribute(t.attrs.method);o&&delete r[o],a&&(n[a].forEach(e=>{e.$el.removeEventListener(e.eventType,e.handler)}),delete n[a])}})});return o.observe(e,{attributes:!0,childList:!0,subtree:!0}),o}};const m={load:s.loadTemplate,app({helpers:e={},template:r,data:n={},methods:o={},partials:a={},watch:i={},hooks:l={},Handlebars:h=(window?window.Handlebars:null),trace:u=!1}){if(!h)throw new Error("ReBars: needs Handlebars in order to run");const f=h.create(),m={renders:{},handlers:{}};return t.setTrace(u),{store:m,instance:f,async render(h){const u=h.nodeType===Node.ELEMENT_NODE?h:document.querySelector(h);if(!u)throw new Error(`ReBars: document.querySelector("${h}") could not be found on the document`);await Promise.all(Object.values(a)),Object.entries(a).forEach(async([e,t])=>f.registerPartial(e,t instanceof Promise?await t:t));const y=f.compile(r instanceof Promise?await r:r),b={$app:u,methods:o,data:"function"==typeof n?n():n};s.registerHelpers({instance:f,helpers:e,scope:b}),d.register({instance:f,template:r,store:m,scope:b}),b.data=c.create(b,async e=>{f.log(t.logLevel(),"ReBars: change",e),p.paths({changed:e,store:m,instance:f}),await s.nextTick(),Object.entries(i).forEach(([t,r])=>{s.shouldRender(e,[t])&&r.call(b.data,s.buildContext(b.data,b))})}),g.start(u,m);const w=s.buildContext(b.data,b);return l.beforeRender&&await l.beforeRender.call(b.data,w),u.innerHTML=y(b.data),l.afterRender&&await l.afterRender.call(b.data,w),w}}}};return window&&(window.ReBars=window.ReBars||m),m})); //# sourceMappingURL=re-bars.umd.min.js.map diff --git a/docs/dist/re-bars.umd.min.js.map b/docs/dist/re-bars.umd.min.js.map index 8b84c78..ca70084 100644 --- a/docs/dist/re-bars.umd.min.js.map +++ b/docs/dist/re-bars.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"re-bars.umd.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/app.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findRef($target, activeRef.ref);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n if ($container.getAttribute(attr) === val) return $container;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findRef: ($target, ref) => {\n if ($target.getAttribute(attrs.ref) === ref) return $target;\n return $target.querySelector(`[${attrs.ref}=\"${ref}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return args.join(\"\");\n });\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n try {\n Utils.setPath(tplScope, path, event.target.value || null);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n const instance = Handlebars.create();\n\n const store = { renders: {}, handlers: {} };\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n const $app = document.querySelector(selector);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n if (!$app)\n return instance.log(3, `ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n const scope = {\n $app,\n methods,\n data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findRef","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","findAttr","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"6LAAA,IAAIA,GAAY,QAED,CACbC,SAAU,IAAOD,EAAY,EAAI,EACjCE,SAAUC,GAAQH,EAAYG,EAE9BC,MAAO,CACLC,MAAO,qBACPC,WAAY,OAGdD,MAAO,CACLE,IAAK,UACLC,MAAO,YACPC,OAAQ,aACRC,IAAK,YCdT,MAAML,MAAEA,GAAUM,QAEH,CACbC,YAAYC,GACV,MAAMC,EAAUC,SAASC,cACnBN,EAAMI,EAAQG,aAAaZ,EAAMK,KAEvC,OAAKG,EAAQK,SAASJ,IAAaJ,EAC5B,CACLA,IAAAA,EACAS,MAAOL,EAAQG,aAAa,SAC5BG,UAAWN,EAAQM,UACnBC,WAAYP,EAAQO,WACpBC,eAAgBR,EAAQQ,gBANqB,MAUjDV,aAAaC,EAASU,GACpB,IAAKA,EAAW,OAEhB,MAAMC,EAASC,KAAKC,QAAQb,EAASU,EAAUb,KAC/C,GAAKc,EAAL,CAGA,GADAA,EAAOG,QACHJ,EAAUD,eAAgB,CAC5B,MAAMM,EAAyB,aAAnBJ,EAAOK,QAAyBN,EAAUD,eAAiBC,EAAUD,eAAiB,EAClGE,EAAOM,kBAAkBF,EAAKA,GAGhCJ,EAAOJ,UAAYG,EAAUH,UAC7BI,EAAOH,WAAaE,EAAUF,WAC1BE,EAAUJ,OAAOK,EAAOO,aAAa,QAASR,EAAUJ,SAG9DP,SAASoB,GACP,MAAMtB,IAAEA,GAAQL,EAGhB,OAFc4B,MAAMC,KAAKF,EAAMG,iBAAiB,IAAIzB,OAEvC0B,OAAO,CAACC,EAAKC,KACxB,MAAM/B,EAAM+B,EAAIrB,aAAaP,GACvB6B,EAASF,EAAI9B,GAEnB,OADA8B,EAAI9B,GAAOgC,EAAS,CAACA,GAAQC,OAAOF,GAAOA,EACpCD,GACN,KAILzB,SAAS6B,EAAMtC,EAAKU,EAAU,MAC5B,MAAM6B,EAAa7B,GAAWE,SAC9B,OAAI2B,EAAWzB,aAAawB,KAAUtC,EAAYuC,EAC3CA,EAAWC,cAAc,IAAIF,MAAStC,QAG/CuB,QAAS,CAACb,EAASH,IACbG,EAAQI,aAAaZ,EAAMK,OAASA,EAAYG,EAC7CA,EAAQ8B,cAAc,IAAItC,EAAMK,QAAQA,OAGjDkC,WAAYC,GAAM9B,SAAS4B,cAAc,IAAItC,EAAMI,WAAWoC,OAC9DC,YAAaD,GAAM9B,SAAS4B,cAAc,IAAItC,EAAMG,UAAUqC,OAC9DE,WAAYT,GAAOA,EAAIU,WAAaC,KAAKC,UAEzCC,QAASC,GACPC,OAAOC,QAAQF,GACZG,IAAI,EAAEhD,EAAKJ,KACS,iBAARA,EAAyB,GAAGI,KAAOJ,IAClC,GAAGI,MAAQJ,MAExBqD,KAAK,KAEV5C,YAAYiC,EAAIY,EAAMC,GACpB,MAAMC,IAAEA,KAAQP,GAAU,CAAEO,IAAK,UAAWD,GAG5C,MAAO,IAAIC,KAFKlC,KAAK0B,QAAQC,MACdK,EAAKG,OAAmC,GAA1B,2BACSvD,EAAMG,UAAUqC,MAAOY,MAASE,MAGxE/C,UAAU6C,GACR,MAAMI,EAAO9C,SAAS+C,cAAc,OAEpC,OADAD,EAAKE,UAAYN,EACVI,IChFX,MAAMG,MAAEA,GAAUC,OAClB,IAAIC,EAAU,QAEC,CACbC,IAAKC,EAELxD,SAASyD,EAAUC,EAAO,EAAGC,GAAY,GACvC,IAAIC,EAAU,KAEd,OAAO,WACL,MAAMC,EAAUF,IAAcC,EACxBE,EAAO,IAAML,EAASM,MAAMlD,KAAMmD,WAExCC,aAAaL,GACbA,EAAUM,WAAWJ,EAAMJ,GAEvBG,GACFC,MAKNK,aAAcC,GACZhB,EAAMgB,GACHC,KAAKC,GAAOA,EAAIC,QAChBC,MAAMC,IACL,MAAM,IAAIC,MAAMD,KAGtBE,SAAU,IACR,IAAIC,QAAQC,IACVX,WAAWW,EAAS,KAGxB7E,QAAQ2B,EAAQmD,EAAMvF,GACpB,MAAMwF,EAAOD,EAAKE,MAAM,KAClBC,EAAOF,EAAKG,MAElB,OADAH,EAAKvD,OAAO,CAAC2D,EAAOC,IAAQD,EAAMC,GAAMzD,GAAQsD,GAAQ1F,EACjDoC,GAGT3B,aAAaqF,GAAOC,KAAEA,EAAIC,KAAEA,EAAIC,QAAEA,IAChC,MAAMC,EAAU,CACdH,KAAAA,EACAI,UAAW7E,KAAK8D,SAChBgB,MAAO9E,KAAK0C,IAAIqC,SAASC,KAAK,KAAMP,GACpCQ,SAAUP,GAGZ,OADAE,EAAQD,QAAU3E,KAAKgF,KAAKL,EAASH,EAAOI,GACrCA,GAGTzF,iBAAgB+F,SAAEA,EAAQC,QAAEA,EAAOX,MAAEA,IACnC,MAAMY,EAAQpF,KACd4B,OAAOC,QAAQsD,GAASE,QAAQ,EAAEC,EAAMC,KACtCL,EAASM,eAAeF,GAAM,YAAYG,GACxC,MAAMb,EAAUQ,EAAMM,aAAa1F,KAAMwE,GACzC,OAAOe,EAAGI,KAAK3F,KAAM4E,KAAYa,QAKvCT,KAAI,CAACpE,EAAK4D,KAAUiB,IACX7D,OAAOgE,KAAKhF,GAAKD,OAAO,CAACkF,EAAO/G,KACrC+G,EAAM/G,GAAO8B,EAAI9B,GAAKkG,KAAKR,KAAUiB,GAC9BI,GACN,IAGLC,aAAc,CAACC,EAASC,IAAaD,EAAQE,KAAKC,GAAUF,EAASC,KAAKlH,GAASmH,EAAOC,MAAMpH,KAChGqH,SAAU,IAAM3D,OCrEH,CACbtD,OAAOqF,EAAO5B,EAAUyD,GAAW,GACjC,IAAIC,EAAM,GAEV,MAAMC,EAAaC,EAAMC,SAAS,KAChC7D,EAAS0D,GACTA,EAAM,KAGFI,EAAYzC,IACXqC,EAAIK,SAAS1C,IAAOqC,EAAIM,KAAK3C,GAClCsC,EAAWD,IAmCb,MAAMO,EAhCN,SAASC,EAAYC,EAAKC,EAAO,IAC/B,OAAO,IAAIC,MAAMF,EAAK,CACpBG,IAAK,SAASpG,EAAQqG,GACpB,MAAMC,EAAQC,QAAQH,OAAO/D,WAE7B,MAAqB,mBAAViE,GAAwBtG,EAAOwG,eAAeH,GAChDC,EAAMpC,KAAK6B,EAAWL,EAAMd,aAAa5E,EAAQ0D,IAEtD4C,GAA0B,iBAAVA,GAAsB,CAAC,QAAS,UAAUT,SAASS,EAAMG,YAAYjC,MAChFwB,EAAYM,EAAOJ,EAAKjG,OAAOoG,KAElCd,GAAUK,EAAUM,EAAKjG,OAAOoG,GAAMpF,KAAK,MACxCqF,IAIXI,IAAK,SAAS1G,EAAQqG,EAAMC,GAC1B,MAAMK,EAAMJ,QAAQG,OAAOrE,WACrBc,EAAO+C,EAAKjG,OAAOoG,GAAMpF,KAAK,KAEpC,OADA2E,EAAUzC,GACHwD,GAGTC,eAAgB,SAAS5G,EAAQqG,GAC/B,MAAMM,EAAMJ,QAAQK,kBAAkBvE,WAChCc,EAAO+C,EAAKjG,OAAOoG,GAAMpF,KAAK,KAEpC,OADA2E,EAAUzC,GACHwD,KAKKX,CAAYtC,EAAME,MACpC,OAAOmC,IC7CX,YAAQjI,GAAUM,QAEH,CACbC,UAAS+F,SAAEA,EAAQyC,SAAEA,EAAQC,MAAEA,EAAKpD,MAAEA,IACpCU,EAASM,eAAe,MAAOF,GAAQ,IAAIJ,EAAS2C,WAAW,GAAGjJ,EAAME,QAAQwG,OAChFJ,EAASM,eAAe,MAAOF,GAAQ,IAAIJ,EAAS2C,WAAW,GAAGjJ,EAAMK,QAAQqG,OAEhFJ,EAASM,eAAe,UAAU,YAAYC,GAE5C,OADAA,EAAKpB,MACEoB,EAAK1D,KAAK,OAGnBmD,EAASM,eAAe,UAAU,YAAYC,GAC5CA,EAAKpB,MACL,MAAOyD,EAAWC,GAAUtC,EAC5B,OAAO,IAAIP,EAAS2C,WAAWC,EAAYC,EAAS,OAGtD7C,EAASM,eAAe,MAAM,YAAYC,GACxC,MAAMxD,KAAEA,GAASwD,EAAKpB,MAChBjD,EAAKoF,EAAMJ,WACX4B,EAAWhI,KAsBjB,OApBA4H,EAAMK,SAAS7G,GAAM,GAErBoF,EAAM1C,WAAWN,MAAK,WACpB,MAAM3C,EAAM2F,EAAM9D,IAAIvB,WAAWC,GAC5BP,GAELe,OAAOC,QAAQI,GAAMoD,QAAQ,EAAE6C,EAAWC,MAClCA,KAAc3D,EAAMG,SAAUO,EAASkD,IAAI,EAAG,YAAYD,sBAAgClG,EAAMpB,GAEtG,MAAMwH,EAAUC,IACd,MAAM1D,EAAU4B,EAAMd,aAAasC,EAAUxD,GAC7CI,EAAQ0D,MAAQA,EAChB1D,EAAQD,QAAQwD,MAAe1C,IAGjCmC,EAAMK,SAAS7G,GAAIwF,KAAK,CAAE/F,IAAAA,EAAKwH,QAAAA,EAASH,UAAAA,IACxCrH,EAAI0H,iBAAiBL,EAAWG,QAI7B,IAAInD,EAAS2C,WAAW,GAAGjJ,EAAMI,WAAWoC,SAGrD8D,EAASM,eAAe,QAAQ,YAAYC,GAC1C,MAAMxD,KAAEA,GAASwD,EAAKpB,MAChB2D,EAAWhI,KACXoB,EAAKoF,EAAMJ,WAqBjB,OAnBAwB,EAAMK,SAAS7G,GAAM,GAErBoF,EAAM1C,WAAWN,KAAK,KACpB,MAAM3C,EAAM2F,EAAM9D,IAAIvB,WAAWC,GAC5BP,GAELe,OAAOC,QAAQI,GAAMoD,QAAQ,EAAE6C,EAAWjE,MACxC,SAASoE,EAAQC,GACf,IACE9B,EAAMgC,QAAQR,EAAU/D,EAAMqE,EAAMxH,OAAOsG,OAAS,MACpD,MAAOxD,GACPsB,EAASkD,IAAI,EAAG,8BAA8BnE,IAAQpD,IAG1D+G,EAAMK,SAAS7G,GAAIwF,KAAK,CAAE/F,IAAAA,EAAKwH,QAAAA,EAASH,UAAAA,IACxCrH,EAAI0H,iBAAiBL,EAAWG,OAI7B,IAAInD,EAAS2C,WAAW,GAAGjJ,EAAMI,WAAWoC,SAGrD8D,EAASM,eAAe,SAAS,YAAYC,GAC3C,MAAMF,GAAEA,EAAEtD,KAAEA,GAASwD,EAAKpB,MACpBoE,EAAMjC,EAAMJ,WAEZnH,EAAM,CACVgF,KAAMwB,EAAKiD,OAAOC,GAAsB,iBAARA,GAChCC,OAAQ,IAAMrD,EAAGvF,OAGnB,IAAKyF,EAAKtD,OAAQ,CAChB,MAAM0G,EAAOC,EAAUC,OACrB,IAAKvE,EAAOE,KAAM1E,MAClBgJ,IACE/J,EAAIgF,KAAO+E,IAEb,GAGFzD,EAAGsD,GAeL,OAZArC,EAAM1C,WAAWN,KAAK,KACpB,MAAM3C,EAAM2F,EAAM9D,IAAIrB,YAAYoH,GAC7B5H,IAEL+G,EAAMqB,QAAQR,GAAO,IAAKxJ,EAAK4B,IAAAA,GAE/B4E,EAAKJ,QAAQpB,IACS,iBAATA,GAAmBiB,EAASkD,IAAI,EAAG,iCAAkC3C,EAAM5E,KAExFqE,EAASkD,IAAIlJ,EAAOV,WAAY,mBAAoBS,EAAIgF,KAAMpD,MAGzD2F,EAAM9D,IAAIwG,YAAYT,EAAKlD,EAAGvF,MAAOiC,QC3GlD,YAAQrD,EAAKD,MAAEA,GAAUO,EAEzB,SAASiK,EAAUC,EAAOC,GACxB,MAAMC,EAAUF,EAAMG,QAAQ5K,EAAMC,MAAO,IACrC4K,EAAUH,EAAME,QAAQ5K,EAAMC,MAAO,IAC3C,OAAO4H,EAAM9D,IAAI+G,UAAUH,GAASI,YAAYlD,EAAM9D,IAAI+G,UAAUD,UAGvD,CACbG,SAAUvK,GACRA,EAAQwK,SAASzH,QACjB/C,EAAQwK,SAASzH,OAAS,GAC1B3B,MAAMC,KAAKrB,EAAQwK,UAAUC,MAAMhJ,GAAOA,EAAIrB,aAAaZ,EAAME,MAEnEgL,WAAY,CAAC1K,EAAS4C,KAAUmH,EAAU/J,EAAQkD,UAAWN,GAE7D7C,SAAQC,QAAEA,EAAO4C,KAAEA,EAAIkD,SAAEA,EAAQ0C,MAAEA,IACjC,MAAMmC,EAAUvD,EAAM9D,IAAI+G,UAAUzH,GAC9BgI,EAAWxJ,MAAMC,KAAKsJ,EAAQH,UAC9BK,EAAQ/K,EAAOV,WAGrBgC,MAAMC,KAAKrB,EAAQwK,UAAUvE,QAAQ6E,IAEA,cAA/BA,EAAG1K,aAAaZ,EAAME,MAAsBoG,EAASkD,IAAI,EAAG,4BAA6B8B,GAE7F,MAAMC,EAAK3D,EAAM9D,IAAI0H,SAASxL,EAAME,IAAKoL,EAAG1K,aAAaZ,EAAME,KAAMiL,GAChEI,EAGOhB,EAAUgB,EAAG7H,UAAW4H,EAAG5H,aACrC4C,EAASkD,IAAI6B,EAAO,mBAAoBC,EAAIC,GAC5CD,EAAGG,YAAYF,EAAGG,WAAU,MAJ5BpF,EAASkD,IAAI6B,EAAO,mBAAoBC,GACxCA,EAAGK,YAQPP,EAAS3E,QAAQ,CAAC8E,EAAIK,KACThE,EAAM9D,IAAI0H,SAASxL,EAAME,IAAKqL,EAAG3K,aAAaZ,EAAME,KAAMM,KAEnE8F,EAASkD,IAAI6B,EAAO,iBAAkBE,GACtC/K,EAAQqL,OAAON,EAAGG,WAAU,OAKhCN,EAAS3E,QAAQ,CAAC8E,EAAIK,KACpB,MAAMN,EAAK9K,EAAQwK,SAASY,GACxBN,EAAG1K,aAAaZ,EAAME,OAASqL,EAAG3K,aAAaZ,EAAME,MAAMoL,EAAGG,YAAYF,EAAGG,WAAU,UC/ClF,CACbnL,OAAM4G,QAAEA,EAAO6B,MAAEA,EAAK1C,SAAEA,IACtBtD,OAAOC,QAAQ+F,EAAMqB,SAClBP,OAAO,EAAEgC,EAAUrC,KACX7B,EAAMV,aAAaC,EAASsC,EAAQpE,OAASuC,EAAM9D,IAAIrB,YAAYqJ,IAE3ErF,QAAQ,EAAEqF,EAAUrC,MACnB,MAAMjJ,EAAUoH,EAAM9D,IAAIrB,YAAYqJ,GAEtC,IAAKtL,EAAS,OAEd,MAAM4C,EAAOqG,EAAQO,SAEf+B,EAAQnE,EAAM9D,IAAIkI,YAAYxL,GAEpC,GAAKyL,EAAMf,WAAW1K,EAAS4C,GAA/B,CAEA,GAAI6I,EAAMlB,SAASvK,GAIjB,OAHA8F,EAASkD,IAAIlJ,EAAOV,WAAY,mBAAoB6J,EAAQpE,KAAM7E,GAClEyL,EAAMC,QAAQ,CAAE1L,QAAAA,EAAS4C,KAAAA,EAAMkD,SAAAA,EAAU0C,MAAAA,SACzCpB,EAAM9D,IAAIqI,aAAa3L,EAASuL,GAKlCvL,EAAQM,MAAMsL,QAAmB,KAAThJ,EAAc,OAAS,GAC/C5C,EAAQkD,UAAYN,EAEpBwE,EAAM9D,IAAIqI,aAAa3L,EAASuL,GAChCzF,EAASkD,IAAIlJ,EAAOV,WAAY,oBAAqB6J,EAAQpE,KAAM7E,UC/B5D,CACbD,MAAMsF,GAAMwE,QAAEA,EAAOhB,SAAEA,IACrB,MAAMgD,EAAW,IAAIC,iBAAiB,EAAEC,MACtCA,EAAOC,aAAa/F,QAAQxE,IAC1B,GAAIA,EAAIU,WAAaC,KAAK6J,aAAc,CACtC,MAAMC,EAAUzK,EAAIrB,aAAaN,EAAON,MAAMG,OACxCwM,EAAY1K,EAAIrB,aAAaN,EAAON,MAAMI,QAC5CsM,UAAgBrC,EAAQqC,GAExBC,IACFtD,EAASsD,GAAWlG,QAAQmG,IAC1BA,EAAK3K,IAAI4K,oBAAoBD,EAAKtD,UAAWsD,EAAKnD,kBAE7CJ,EAASsD,SAOxB,OADAN,EAASS,QAAQjH,EAAM,CAAEkH,YAAY,EAAMC,WAAW,EAAMC,SAAS,IAC9DZ,ICfX,MAAMa,EAAS,CACbC,KAAMvF,EAAMlD,aACZnE,KAAIgG,QACFA,EAAU,GAAEwC,SACZA,EAAQjD,KACRA,EAAO,GAAEC,QACTA,EAAU,GAAEqH,SACZA,EAAW,GAAEjN,MACbA,EAAQ,GAAEkN,MACVA,EAAQ,GAAEC,WACVA,GAAa1J,OAASA,OAAO0J,WAAa,MAAIC,MAC9CA,GAAQ,IAER,MAAMjH,EAAWgH,EAAWnD,SAEtBnB,EAAQ,CAAEqB,QAAS,GAAIhB,SAAU,IACvC,IAAKiE,EAAY,MAAM,IAAIrI,MAAM,4CAIjC,OAFA3E,EAAOT,SAAS0N,GAET,CACLvE,MAAAA,EACA1C,SAAAA,EACA/F,aAAaiN,GACX,MAAM3H,EAAOnF,SAAS4B,cAAckL,SAG9BrI,QAAQsI,IAAIzK,OAAO0K,OAAON,IAChCpK,OAAOC,QAAQmK,GAAU3G,QAAQkH,OAAQjH,EAAMkH,KAC7CtH,EAASuH,gBAAgBnH,EAAMkH,aAAezI,cAAgByI,EAAMA,IAItE,MAAME,EAAaxH,EAASyH,QAAQhF,aAAoB5D,cAAgB4D,EAAWA,GAEnF,IAAKlD,EACH,OAAOS,EAASkD,IAAI,EAAG,mCAAmCgE,0CAE5D,MAAM5H,EAAQ,CACZC,KAAAA,EACAE,QAAAA,EACAD,KAAAA,GAGF8B,EAAMoG,gBAAgB,CAAE1H,SAAAA,EAAUC,QAAAA,EAASX,MAAAA,IAC3CqI,EAAQC,SAAS,CAAE5H,SAAAA,EAAUyC,SAAAA,EAAUC,MAAAA,EAAOpD,MAAAA,IAE9CA,EAAME,KAAOoE,EAAUC,OAAOvE,EAAO+H,MAAAA,IACnCrH,EAASkD,IAAIlJ,EAAOV,WAAY,iBAAkBuH,GAClDgH,EAAS/D,MAAM,CAAEjD,QAAAA,EAAS6B,MAAAA,EAAO1C,SAAAA,UAE3BsB,EAAM1C,WACZlC,OAAOC,QAAQ9C,GAAOsG,QAAQ,EAAEpB,EAAMsB,MAChCiB,EAAMV,aAAaC,EAAS,CAAC9B,KAAQsB,EAAGI,KAAKnB,EAAME,KAAM8B,EAAMd,aAAalB,EAAME,KAAMF,QAIhGwI,EAAQC,MAAMxI,EAAMmD,GACpB,MAAMhD,EAAU4B,EAAMd,aAAalB,EAAME,KAAMF,GAE3CyH,EAAMiB,oBAAoBjB,EAAMiB,aAAavH,KAAKnB,EAAME,KAAME,GAClEH,EAAKnC,UAAYoK,EAAWlI,EAAME,MAC9BuH,EAAMkB,mBAAmBlB,EAAMkB,YAAYxH,KAAKnB,EAAME,KAAME,cAOpEpC,SAAQA,OAAOsJ,OAAStJ,OAAOsJ,QAAUA"} \ No newline at end of file +{"version":3,"file":"re-bars.umd.min.js","sources":["../src/config.js","../src/utils/dom.js","../src/utils/index.js","../src/proxy-trap.js","../src/helpers.js","../src/utils/patch.js","../src/re-render.js","../src/garbage.js","../src/index.js"],"sourcesContent":["let isTracing = false;\n\nexport default {\n logLevel: () => (isTracing ? 1 : 0),\n setTrace: val => (isTracing = val),\n\n regex: {\n attrs: /rbs-(.*?)=\"(.*?)\"/g,\n whitespace: /\\s/g,\n },\n\n attrs: {\n key: \"rbs-key\",\n watch: \"rbs-watch\",\n method: \"rbs-method\",\n ref: \"rbs-ref\",\n },\n};\n","import Config from \"../config.js\";\nconst { attrs } = Config;\n\nexport default {\n recordState($target) {\n const $active = document.activeElement;\n const ref = $active.getAttribute(attrs.ref);\n\n if (!$target.contains($active) || !ref) return null;\n return {\n ref,\n style: $active.getAttribute(\"style\"),\n scrollTop: $active.scrollTop,\n scrollLeft: $active.scrollLeft,\n selectionStart: $active.selectionStart,\n };\n },\n\n restoreState($target, activeRef) {\n if (!activeRef) return;\n\n const $input = this.findAttr(attrs.ref, activeRef.ref, $target);\n if (!$input) return;\n\n $input.focus();\n if (activeRef.selectionStart) {\n const pos = $input.tagName === \"TEXTAREA\" ? activeRef.selectionStart : activeRef.selectionStart + 1;\n $input.setSelectionRange(pos, pos);\n }\n\n $input.scrollTop = activeRef.scrollTop;\n $input.scrollLeft = activeRef.scrollLeft;\n if (activeRef.style) $input.setAttribute(\"style\", activeRef.style);\n },\n\n findRefs($root) {\n const { ref } = attrs;\n const $refs = Array.from($root.querySelectorAll(`[${ref}]`));\n\n return $refs.reduce((obj, $el) => {\n const key = $el.getAttribute(ref);\n const target = obj[key];\n obj[key] = target ? [target].concat($el) : $el;\n return obj;\n }, {});\n },\n\n // use this in place of all the others that are repeated eventually...\n findAttr(attr, val, $target = null) {\n const $container = $target || document;\n // check top level\n if ($target && $target.getAttribute(attr) === val) return $target;\n return $container.querySelector(`[${attr}=\"${val}\"]`);\n },\n\n findMethod: id => document.querySelector(`[${attrs.method}=\"${id}\"]`),\n findWatcher: id => document.querySelector(`[${attrs.watch}=\"${id}\"]`),\n isTextNode: $el => $el.nodeType === Node.TEXT_NODE,\n\n propStr: props =>\n Object.entries(props)\n .map(([key, val]) => {\n if (typeof val === \"number\") return `${key}=${val}`;\n else return `${key}=\"${val}\"`;\n })\n .join(\" \"),\n\n wrapWatcher(id, html, hash) {\n const { tag, ...props } = { tag: \"span\", ...hash };\n const propStr = this.propStr(props);\n const style = !html.length ? \"style='display:none;'\" : \"\";\n return `<${tag} ${propStr} ${style} ${attrs.watch}=\"${id}\">${html}`;\n },\n\n getShadow(html) {\n const $tmp = document.createElement(\"div\");\n $tmp.innerHTML = html;\n return $tmp;\n },\n};\n","import Dom from \"./dom.js\";\nconst { fetch } = window;\nlet counter = 1;\n\nexport default {\n dom: Dom,\n\n debounce(callback, wait = 0, immediate = false) {\n let timeout = null;\n\n return function() {\n const callNow = immediate && !timeout;\n const next = () => callback.apply(this, arguments);\n\n clearTimeout(timeout);\n timeout = setTimeout(next, wait);\n\n if (callNow) {\n next();\n }\n };\n },\n\n loadTemplate: file =>\n fetch(file)\n .then(res => res.text())\n .catch(err => {\n throw new Error(err);\n }),\n\n nextTick: () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n }),\n\n setPath(target, path, val) {\n const segs = path.split(\".\");\n const last = segs.pop();\n segs.reduce((point, seg) => point[seg], target)[last] = val;\n return target;\n },\n\n buildContext(scope, { $app, data, methods }) {\n const context = {\n $app,\n $nextTick: this.nextTick,\n $refs: this.dom.findRefs.bind(null, $app),\n rootData: data,\n };\n context.methods = this.bind(methods, scope, context);\n return context;\n },\n\n registerHelpers({ instance, helpers, scope }) {\n const utils = this;\n Object.entries(helpers).forEach(([name, fn]) =>\n instance.registerHelper(name, function(...args) {\n const context = utils.buildContext(this, scope);\n return fn.call(this, context, ...args);\n })\n );\n },\n\n bind(obj, scope, ...args) {\n return Object.keys(obj).reduce((bound, key) => {\n bound[key] = obj[key].bind(scope, ...args);\n return bound;\n }, {});\n },\n\n shouldRender: (changed, watching) => changed.some(change => watching.some(watch => change.match(watch))),\n randomId: () => counter++,\n};\n","import Utils from \"./utils/index.js\";\n\nexport default {\n create(scope, callback, trackGet = false) {\n let que = [];\n\n const _debounced = Utils.debounce(() => {\n callback(que);\n que = [];\n });\n\n const _addToQue = path => {\n if (!que.includes(path)) que.push(path);\n _debounced(que);\n };\n\n function _buildProxy(raw, tree = []) {\n return new Proxy(raw, {\n get: function(target, prop) {\n const value = Reflect.get(...arguments);\n\n if (typeof value === \"function\" && target.hasOwnProperty(prop))\n return value.bind(proxyData, Utils.buildContext(target, scope));\n\n if (value && typeof value === \"object\" && [\"Array\", \"Object\"].includes(value.constructor.name)) {\n return _buildProxy(value, tree.concat(prop));\n } else {\n if (trackGet) _addToQue(tree.concat(prop).join(\".\"));\n return value;\n }\n },\n\n set: function(target, prop, value) {\n const ret = Reflect.set(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n\n deleteProperty: function(target, prop) {\n const ret = Reflect.deleteProperty(...arguments);\n const path = tree.concat(prop).join(\".\");\n _addToQue(path);\n return ret;\n },\n });\n }\n\n const proxyData = _buildProxy(scope.data);\n return proxyData;\n },\n};\n","import Utils from \"./utils/index.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Config from \"./config.js\";\n\nconst { attrs } = Config;\n\nexport default {\n register({ instance, template, store, scope }) {\n instance.registerHelper(\"key\", name => new instance.SafeString(`${attrs.key}=\"${name}\"`));\n instance.registerHelper(\"ref\", name => new instance.SafeString(`${attrs.ref}=\"${name}\"`));\n\n instance.registerHelper(\"onlyIf\", function(...args) {\n args.pop();\n const [condition, string] = args;\n return new instance.SafeString(condition ? string : \"\");\n });\n\n instance.registerHelper(\"concat\", function(...args) {\n args.pop();\n return new instance.SafeString(args.join(\"\"));\n });\n\n instance.registerHelper(\"on\", function(...args) {\n const { hash } = args.pop();\n const id = Utils.randomId();\n const tplScope = this;\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(function() {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, methodName]) => {\n if (!(methodName in scope.methods)) instance.log(3, `ReBars: \"${methodName}\" is not a method.`, hash, $el);\n\n const handler = event => {\n const context = Utils.buildContext(tplScope, scope);\n context.event = event;\n context.methods[methodName](...args);\n };\n\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"bind\", function(...args) {\n const { hash } = args.pop();\n const [forceValue] = args;\n const tplScope = this;\n const id = Utils.randomId();\n\n store.handlers[id] = [];\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findMethod(id);\n if (!$el) return;\n\n Object.entries(hash).forEach(([eventType, path]) => {\n function handler(event) {\n let value = event.target.value;\n value = value === \"\" ? null : value;\n\n try {\n Utils.setPath(tplScope, path, forceValue || value);\n } catch (err) {\n instance.log(3, `ReBars: could not set path ${path}`, $el);\n }\n }\n store.handlers[id].push({ $el, handler, eventType });\n $el.addEventListener(eventType, handler);\n });\n });\n\n return new instance.SafeString(`${attrs.method}=\"${id}\"`);\n });\n\n instance.registerHelper(\"watch\", function(...args) {\n const { fn, hash } = args.pop();\n const eId = Utils.randomId();\n\n const ref = {\n path: args.filter(arg => typeof arg === \"string\"),\n render: () => fn(this),\n };\n\n if (!args.length) {\n const trap = ProxyTrap.create(\n { ...scope, data: this },\n paths => {\n ref.path = paths;\n },\n true\n );\n\n fn(trap);\n }\n\n Utils.nextTick().then(() => {\n const $el = Utils.dom.findWatcher(eId);\n if (!$el) return;\n\n store.renders[eId] = { ...ref, $el };\n\n args.forEach(path => {\n if (typeof path !== \"string\") instance.log(3, \"ReBars: can only watch Strings\", args, $el);\n });\n instance.log(Config.logLevel(), \"ReBars: watching\", ref.path, $el);\n });\n\n return Utils.dom.wrapWatcher(eId, fn(this), hash);\n });\n },\n};\n","import Utils from \"./index.js\";\nimport Config from \"../config.js\";\n\nconst { attrs, regex } = Config;\n\nfunction _isEqHtml(html1, html2) {\n const parsed1 = html1.replace(regex.attrs, \"\");\n const parsed2 = html2.replace(regex.attrs, \"\");\n return Utils.dom.getShadow(parsed1).isEqualNode(Utils.dom.getShadow(parsed2));\n}\n\nexport default {\n canPatch: $target =>\n $target.children.length &&\n $target.children.length > 1 &&\n Array.from($target.children).every($el => $el.getAttribute(attrs.key)),\n\n hasChanged: ($target, html) => !_isEqHtml($target.innerHTML, html),\n\n compare({ $target, html, instance, store }) {\n const $shadow = Utils.dom.getShadow(html);\n const $vChilds = Array.from($shadow.children);\n const level = Config.logLevel();\n\n // deletes and updates\n Array.from($target.children).forEach($r => {\n // warn with the real element if we have an undefined key\n if ($r.getAttribute(attrs.key) === \"undefined\") instance.log(3, \"ReBars: key was undefined\", $r);\n\n const $v = Utils.dom.findAttr(attrs.key, $r.getAttribute(attrs.key), $shadow);\n if (!$v) {\n instance.log(level, \"ReBars: removing\", $r);\n $r.remove();\n } else if (!_isEqHtml($v.innerHTML, $r.innerHTML, true)) {\n instance.log(level, \"ReBars: updating\", $r, $v);\n $r.replaceWith($v.cloneNode(true));\n }\n });\n\n // additions\n $vChilds.forEach(($v, index) => {\n const $r = Utils.dom.findAttr(attrs.key, $v.getAttribute(attrs.key), $target);\n if (!$r) {\n instance.log(level, \"ReBars: adding\", $v);\n $target.append($v.cloneNode(true));\n }\n });\n\n // sorting\n $vChilds.forEach(($v, index) => {\n const $r = $target.children[index];\n if ($r.getAttribute(attrs.key) !== $v.getAttribute(attrs.key)) $r.replaceWith($v.cloneNode(true));\n });\n },\n};\n","import Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Patch from \"./utils/patch.js\";\n\nexport default {\n paths({ changed, store, instance }) {\n Object.entries(store.renders)\n .filter(([renderId, handler]) => {\n return Utils.shouldRender(changed, handler.path) && Utils.dom.findWatcher(renderId);\n })\n .forEach(([renderId, handler]) => {\n const $target = Utils.dom.findWatcher(renderId);\n // if we cant find the target, we should not attempt to re-renders\n if (!$target) return;\n\n const html = handler.render();\n // cursor position focused element ect...\n const stash = Utils.dom.recordState($target);\n\n if (!Patch.hasChanged($target, html)) return;\n\n if (Patch.canPatch($target)) {\n instance.log(Config.logLevel(), \"ReBars: patching\", handler.path, $target);\n Patch.compare({ $target, html, instance, store });\n Utils.dom.restoreState($target, stash);\n return;\n }\n\n // we dont want wrappers to show up with no content\n $target.style.display = html === \"\" ? \"none\" : \"\";\n $target.innerHTML = html;\n // restore saved state of DOM\n Utils.dom.restoreState($target, stash);\n instance.log(Config.logLevel(), \"ReBars: re-render\", handler.path, $target);\n });\n },\n};\n","import Config from \"./config.js\";\n\nexport default {\n start($app, { renders, handlers }) {\n const observer = new MutationObserver(([record]) => {\n record.removedNodes.forEach($el => {\n if ($el.nodeType === Node.ELEMENT_NODE) {\n const watchId = $el.getAttribute(Config.attrs.watch);\n const handlerId = $el.getAttribute(Config.attrs.method);\n if (watchId) delete renders[watchId];\n\n if (handlerId) {\n handlers[handlerId].forEach(item => {\n item.$el.removeEventListener(item.eventType, item.handler);\n });\n delete handlers[handlerId];\n }\n }\n });\n });\n\n observer.observe($app, { attributes: true, childList: true, subtree: true });\n return observer;\n },\n};\n","import Helpers from \"./helpers.js\";\nimport ReRender from \"./re-render.js\";\nimport ProxyTrap from \"./proxy-trap.js\";\nimport Utils from \"./utils/index.js\";\nimport Config from \"./config.js\";\nimport Garbage from \"./garbage.js\";\n\nconst ReBars = {\n load: Utils.loadTemplate,\n app({\n helpers = {},\n template,\n data = {},\n methods = {},\n partials = {},\n watch = {},\n hooks = {},\n Handlebars = window ? window.Handlebars : null,\n trace = false,\n }) {\n if (!Handlebars) throw new Error(\"ReBars: needs Handlebars in order to run\");\n\n const instance = Handlebars.create();\n const store = { renders: {}, handlers: {} };\n Config.setTrace(trace);\n\n return {\n store,\n instance,\n async render(selector) {\n // takes an element or a selector\n const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector);\n\n if (!$app) throw new Error(`ReBars: document.querySelector(\"${selector}\") could not be found on the document`);\n\n // have to make sure they are resolved first\n await Promise.all(Object.values(partials));\n Object.entries(partials).forEach(async ([name, tpl]) =>\n instance.registerPartial(name, tpl instanceof Promise ? await tpl : tpl)\n );\n\n // must be compiled after the partials\n const templateFn = instance.compile(template instanceof Promise ? await template : template);\n\n const scope = {\n $app,\n methods,\n data: typeof data === \"function\" ? data() : data,\n };\n\n Utils.registerHelpers({ instance, helpers, scope });\n Helpers.register({ instance, template, store, scope });\n\n scope.data = ProxyTrap.create(scope, async changed => {\n instance.log(Config.logLevel(), \"ReBars: change\", changed);\n ReRender.paths({ changed, store, instance });\n // have to wait a tick or anything set by a watch will not catch...\n await Utils.nextTick();\n Object.entries(watch).forEach(([path, fn]) => {\n if (Utils.shouldRender(changed, [path])) fn.call(scope.data, Utils.buildContext(scope.data, scope));\n });\n });\n\n Garbage.start($app, store);\n const context = Utils.buildContext(scope.data, scope);\n\n if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context);\n $app.innerHTML = templateFn(scope.data);\n if (hooks.afterRender) await hooks.afterRender.call(scope.data, context);\n\n return context;\n },\n };\n },\n};\n\n// add it to the window if we have one...\nif (window) window.ReBars = window.ReBars || ReBars;\nexport default ReBars;\n"],"names":["isTracing","logLevel","setTrace","val","regex","attrs","whitespace","key","watch","method","ref","Config","[object Object]","$target","$active","document","activeElement","getAttribute","contains","style","scrollTop","scrollLeft","selectionStart","activeRef","$input","this","findAttr","focus","pos","tagName","setSelectionRange","setAttribute","$root","Array","from","querySelectorAll","reduce","obj","$el","target","concat","attr","$container","querySelector","findMethod","id","findWatcher","isTextNode","nodeType","Node","TEXT_NODE","propStr","props","Object","entries","map","join","html","hash","tag","length","$tmp","createElement","innerHTML","fetch","window","counter","dom","Dom","callback","wait","immediate","timeout","callNow","next","apply","arguments","clearTimeout","setTimeout","loadTemplate","file","then","res","text","catch","err","Error","nextTick","Promise","resolve","path","segs","split","last","pop","point","seg","scope","$app","data","methods","context","$nextTick","$refs","findRefs","bind","rootData","instance","helpers","utils","forEach","name","fn","registerHelper","args","buildContext","call","keys","bound","shouldRender","changed","watching","some","change","match","randomId","trackGet","que","_debounced","Utils","debounce","_addToQue","includes","push","proxyData","_buildProxy","raw","tree","Proxy","get","prop","value","Reflect","hasOwnProperty","constructor","set","ret","deleteProperty","template","store","SafeString","condition","string","tplScope","handlers","eventType","methodName","log","handler","event","addEventListener","forceValue","setPath","eId","filter","arg","render","trap","ProxyTrap","create","paths","renders","wrapWatcher","_isEqHtml","html1","html2","parsed1","replace","parsed2","getShadow","isEqualNode","canPatch","children","every","hasChanged","$shadow","$vChilds","level","$r","$v","replaceWith","cloneNode","remove","index","append","renderId","stash","recordState","Patch","compare","restoreState","display","observer","MutationObserver","record","removedNodes","ELEMENT_NODE","watchId","handlerId","item","removeEventListener","observe","attributes","childList","subtree","ReBars","load","partials","hooks","Handlebars","trace","selector","all","values","async","tpl","registerPartial","templateFn","compile","registerHelpers","Helpers","register","ReRender","Garbage","start","beforeRender","afterRender"],"mappings":"6LAAA,IAAIA,GAAY,QAED,CACbC,SAAU,IAAOD,EAAY,EAAI,EACjCE,SAAUC,GAAQH,EAAYG,EAE9BC,MAAO,CACLC,MAAO,qBACPC,WAAY,OAGdD,MAAO,CACLE,IAAK,UACLC,MAAO,YACPC,OAAQ,aACRC,IAAK,YCdT,MAAML,MAAEA,GAAUM,QAEH,CACbC,YAAYC,GACV,MAAMC,EAAUC,SAASC,cACnBN,EAAMI,EAAQG,aAAaZ,EAAMK,KAEvC,OAAKG,EAAQK,SAASJ,IAAaJ,EAC5B,CACLA,IAAAA,EACAS,MAAOL,EAAQG,aAAa,SAC5BG,UAAWN,EAAQM,UACnBC,WAAYP,EAAQO,WACpBC,eAAgBR,EAAQQ,gBANqB,MAUjDV,aAAaC,EAASU,GACpB,IAAKA,EAAW,OAEhB,MAAMC,EAASC,KAAKC,SAASrB,EAAMK,IAAKa,EAAUb,IAAKG,GACvD,GAAKW,EAAL,CAGA,GADAA,EAAOG,QACHJ,EAAUD,eAAgB,CAC5B,MAAMM,EAAyB,aAAnBJ,EAAOK,QAAyBN,EAAUD,eAAiBC,EAAUD,eAAiB,EAClGE,EAAOM,kBAAkBF,EAAKA,GAGhCJ,EAAOJ,UAAYG,EAAUH,UAC7BI,EAAOH,WAAaE,EAAUF,WAC1BE,EAAUJ,OAAOK,EAAOO,aAAa,QAASR,EAAUJ,SAG9DP,SAASoB,GACP,MAAMtB,IAAEA,GAAQL,EAGhB,OAFc4B,MAAMC,KAAKF,EAAMG,iBAAiB,IAAIzB,OAEvC0B,OAAO,CAACC,EAAKC,KACxB,MAAM/B,EAAM+B,EAAIrB,aAAaP,GACvB6B,EAASF,EAAI9B,GAEnB,OADA8B,EAAI9B,GAAOgC,EAAS,CAACA,GAAQC,OAAOF,GAAOA,EACpCD,GACN,KAILzB,SAAS6B,EAAMtC,EAAKU,EAAU,MAC5B,MAAM6B,EAAa7B,GAAWE,SAE9B,OAAIF,GAAWA,EAAQI,aAAawB,KAAUtC,EAAYU,EACnD6B,EAAWC,cAAc,IAAIF,MAAStC,QAG/CyC,WAAYC,GAAM9B,SAAS4B,cAAc,IAAItC,EAAMI,WAAWoC,OAC9DC,YAAaD,GAAM9B,SAAS4B,cAAc,IAAItC,EAAMG,UAAUqC,OAC9DE,WAAYT,GAAOA,EAAIU,WAAaC,KAAKC,UAEzCC,QAASC,GACPC,OAAOC,QAAQF,GACZG,IAAI,EAAEhD,EAAKJ,KACS,iBAARA,EAAyB,GAAGI,KAAOJ,IAClC,GAAGI,MAAQJ,MAExBqD,KAAK,KAEV5C,YAAYiC,EAAIY,EAAMC,GACpB,MAAMC,IAAEA,KAAQP,GAAU,CAAEO,IAAK,UAAWD,GAG5C,MAAO,IAAIC,KAFKlC,KAAK0B,QAAQC,MACdK,EAAKG,OAAmC,GAA1B,2BACSvD,EAAMG,UAAUqC,MAAOY,MAASE,MAGxE/C,UAAU6C,GACR,MAAMI,EAAO9C,SAAS+C,cAAc,OAEpC,OADAD,EAAKE,UAAYN,EACVI,IC5EX,MAAMG,MAAEA,GAAUC,OAClB,IAAIC,EAAU,QAEC,CACbC,IAAKC,EAELxD,SAASyD,EAAUC,EAAO,EAAGC,GAAY,GACvC,IAAIC,EAAU,KAEd,OAAO,WACL,MAAMC,EAAUF,IAAcC,EACxBE,EAAO,IAAML,EAASM,MAAMlD,KAAMmD,WAExCC,aAAaL,GACbA,EAAUM,WAAWJ,EAAMJ,GAEvBG,GACFC,MAKNK,aAAcC,GACZhB,EAAMgB,GACHC,KAAKC,GAAOA,EAAIC,QAChBC,MAAMC,IACL,MAAM,IAAIC,MAAMD,KAGtBE,SAAU,IACR,IAAIC,QAAQC,IACVX,WAAWW,EAAS,KAGxB7E,QAAQ2B,EAAQmD,EAAMvF,GACpB,MAAMwF,EAAOD,EAAKE,MAAM,KAClBC,EAAOF,EAAKG,MAElB,OADAH,EAAKvD,OAAO,CAAC2D,EAAOC,IAAQD,EAAMC,GAAMzD,GAAQsD,GAAQ1F,EACjDoC,GAGT3B,aAAaqF,GAAOC,KAAEA,EAAIC,KAAEA,EAAIC,QAAEA,IAChC,MAAMC,EAAU,CACdH,KAAAA,EACAI,UAAW7E,KAAK8D,SAChBgB,MAAO9E,KAAK0C,IAAIqC,SAASC,KAAK,KAAMP,GACpCQ,SAAUP,GAGZ,OADAE,EAAQD,QAAU3E,KAAKgF,KAAKL,EAASH,EAAOI,GACrCA,GAGTzF,iBAAgB+F,SAAEA,EAAQC,QAAEA,EAAOX,MAAEA,IACnC,MAAMY,EAAQpF,KACd4B,OAAOC,QAAQsD,GAASE,QAAQ,EAAEC,EAAMC,KACtCL,EAASM,eAAeF,GAAM,YAAYG,GACxC,MAAMb,EAAUQ,EAAMM,aAAa1F,KAAMwE,GACzC,OAAOe,EAAGI,KAAK3F,KAAM4E,KAAYa,QAKvCT,KAAI,CAACpE,EAAK4D,KAAUiB,IACX7D,OAAOgE,KAAKhF,GAAKD,OAAO,CAACkF,EAAO/G,KACrC+G,EAAM/G,GAAO8B,EAAI9B,GAAKkG,KAAKR,KAAUiB,GAC9BI,GACN,IAGLC,aAAc,CAACC,EAASC,IAAaD,EAAQE,KAAKC,GAAUF,EAASC,KAAKlH,GAASmH,EAAOC,MAAMpH,KAChGqH,SAAU,IAAM3D,OCrEH,CACbtD,OAAOqF,EAAO5B,EAAUyD,GAAW,GACjC,IAAIC,EAAM,GAEV,MAAMC,EAAaC,EAAMC,SAAS,KAChC7D,EAAS0D,GACTA,EAAM,KAGFI,EAAYzC,IACXqC,EAAIK,SAAS1C,IAAOqC,EAAIM,KAAK3C,GAClCsC,EAAWD,IAmCb,MAAMO,EAhCN,SAASC,EAAYC,EAAKC,EAAO,IAC/B,OAAO,IAAIC,MAAMF,EAAK,CACpBG,IAAK,SAASpG,EAAQqG,GACpB,MAAMC,EAAQC,QAAQH,OAAO/D,WAE7B,MAAqB,mBAAViE,GAAwBtG,EAAOwG,eAAeH,GAChDC,EAAMpC,KAAK6B,EAAWL,EAAMd,aAAa5E,EAAQ0D,IAEtD4C,GAA0B,iBAAVA,GAAsB,CAAC,QAAS,UAAUT,SAASS,EAAMG,YAAYjC,MAChFwB,EAAYM,EAAOJ,EAAKjG,OAAOoG,KAElCd,GAAUK,EAAUM,EAAKjG,OAAOoG,GAAMpF,KAAK,MACxCqF,IAIXI,IAAK,SAAS1G,EAAQqG,EAAMC,GAC1B,MAAMK,EAAMJ,QAAQG,OAAOrE,WACrBc,EAAO+C,EAAKjG,OAAOoG,GAAMpF,KAAK,KAEpC,OADA2E,EAAUzC,GACHwD,GAGTC,eAAgB,SAAS5G,EAAQqG,GAC/B,MAAMM,EAAMJ,QAAQK,kBAAkBvE,WAChCc,EAAO+C,EAAKjG,OAAOoG,GAAMpF,KAAK,KAEpC,OADA2E,EAAUzC,GACHwD,KAKKX,CAAYtC,EAAME,MACpC,OAAOmC,IC7CX,YAAQjI,GAAUM,QAEH,CACbC,UAAS+F,SAAEA,EAAQyC,SAAEA,EAAQC,MAAEA,EAAKpD,MAAEA,IACpCU,EAASM,eAAe,MAAOF,GAAQ,IAAIJ,EAAS2C,WAAW,GAAGjJ,EAAME,QAAQwG,OAChFJ,EAASM,eAAe,MAAOF,GAAQ,IAAIJ,EAAS2C,WAAW,GAAGjJ,EAAMK,QAAQqG,OAEhFJ,EAASM,eAAe,UAAU,YAAYC,GAC5CA,EAAKpB,MACL,MAAOyD,EAAWC,GAAUtC,EAC5B,OAAO,IAAIP,EAAS2C,WAAWC,EAAYC,EAAS,OAGtD7C,EAASM,eAAe,UAAU,YAAYC,GAE5C,OADAA,EAAKpB,MACE,IAAIa,EAAS2C,WAAWpC,EAAK1D,KAAK,QAG3CmD,EAASM,eAAe,MAAM,YAAYC,GACxC,MAAMxD,KAAEA,GAASwD,EAAKpB,MAChBjD,EAAKoF,EAAMJ,WACX4B,EAAWhI,KAsBjB,OApBA4H,EAAMK,SAAS7G,GAAM,GAErBoF,EAAM1C,WAAWN,MAAK,WACpB,MAAM3C,EAAM2F,EAAM9D,IAAIvB,WAAWC,GAC5BP,GAELe,OAAOC,QAAQI,GAAMoD,QAAQ,EAAE6C,EAAWC,MAClCA,KAAc3D,EAAMG,SAAUO,EAASkD,IAAI,EAAG,YAAYD,sBAAgClG,EAAMpB,GAEtG,MAAMwH,EAAUC,IACd,MAAM1D,EAAU4B,EAAMd,aAAasC,EAAUxD,GAC7CI,EAAQ0D,MAAQA,EAChB1D,EAAQD,QAAQwD,MAAe1C,IAGjCmC,EAAMK,SAAS7G,GAAIwF,KAAK,CAAE/F,IAAAA,EAAKwH,QAAAA,EAASH,UAAAA,IACxCrH,EAAI0H,iBAAiBL,EAAWG,QAI7B,IAAInD,EAAS2C,WAAW,GAAGjJ,EAAMI,WAAWoC,SAGrD8D,EAASM,eAAe,QAAQ,YAAYC,GAC1C,MAAMxD,KAAEA,GAASwD,EAAKpB,OACfmE,GAAc/C,EACfuC,EAAWhI,KACXoB,EAAKoF,EAAMJ,WAwBjB,OAtBAwB,EAAMK,SAAS7G,GAAM,GAErBoF,EAAM1C,WAAWN,KAAK,KACpB,MAAM3C,EAAM2F,EAAM9D,IAAIvB,WAAWC,GAC5BP,GAELe,OAAOC,QAAQI,GAAMoD,QAAQ,EAAE6C,EAAWjE,MACxC,SAASoE,EAAQC,GACf,IAAIlB,EAAQkB,EAAMxH,OAAOsG,MACzBA,EAAkB,KAAVA,EAAe,KAAOA,EAE9B,IACEZ,EAAMiC,QAAQT,EAAU/D,EAAMuE,GAAcpB,GAC5C,MAAOxD,GACPsB,EAASkD,IAAI,EAAG,8BAA8BnE,IAAQpD,IAG1D+G,EAAMK,SAAS7G,GAAIwF,KAAK,CAAE/F,IAAAA,EAAKwH,QAAAA,EAASH,UAAAA,IACxCrH,EAAI0H,iBAAiBL,EAAWG,OAI7B,IAAInD,EAAS2C,WAAW,GAAGjJ,EAAMI,WAAWoC,SAGrD8D,EAASM,eAAe,SAAS,YAAYC,GAC3C,MAAMF,GAAEA,EAAEtD,KAAEA,GAASwD,EAAKpB,MACpBqE,EAAMlC,EAAMJ,WAEZnH,EAAM,CACVgF,KAAMwB,EAAKkD,OAAOC,GAAsB,iBAARA,GAChCC,OAAQ,IAAMtD,EAAGvF,OAGnB,IAAKyF,EAAKtD,OAAQ,CAChB,MAAM2G,EAAOC,EAAUC,OACrB,IAAKxE,EAAOE,KAAM1E,MAClBiJ,IACEhK,EAAIgF,KAAOgF,IAEb,GAGF1D,EAAGuD,GAeL,OAZAtC,EAAM1C,WAAWN,KAAK,KACpB,MAAM3C,EAAM2F,EAAM9D,IAAIrB,YAAYqH,GAC7B7H,IAEL+G,EAAMsB,QAAQR,GAAO,IAAKzJ,EAAK4B,IAAAA,GAE/B4E,EAAKJ,QAAQpB,IACS,iBAATA,GAAmBiB,EAASkD,IAAI,EAAG,iCAAkC3C,EAAM5E,KAExFqE,EAASkD,IAAIlJ,EAAOV,WAAY,mBAAoBS,EAAIgF,KAAMpD,MAGzD2F,EAAM9D,IAAIyG,YAAYT,EAAKnD,EAAGvF,MAAOiC,QC/GlD,YAAQrD,EAAKD,MAAEA,GAAUO,EAEzB,SAASkK,EAAUC,EAAOC,GACxB,MAAMC,EAAUF,EAAMG,QAAQ7K,EAAMC,MAAO,IACrC6K,EAAUH,EAAME,QAAQ7K,EAAMC,MAAO,IAC3C,OAAO4H,EAAM9D,IAAIgH,UAAUH,GAASI,YAAYnD,EAAM9D,IAAIgH,UAAUD,UAGvD,CACbG,SAAUxK,GACRA,EAAQyK,SAAS1H,QACjB/C,EAAQyK,SAAS1H,OAAS,GAC1B3B,MAAMC,KAAKrB,EAAQyK,UAAUC,MAAMjJ,GAAOA,EAAIrB,aAAaZ,EAAME,MAEnEiL,WAAY,CAAC3K,EAAS4C,KAAUoH,EAAUhK,EAAQkD,UAAWN,GAE7D7C,SAAQC,QAAEA,EAAO4C,KAAEA,EAAIkD,SAAEA,EAAQ0C,MAAEA,IACjC,MAAMoC,EAAUxD,EAAM9D,IAAIgH,UAAU1H,GAC9BiI,EAAWzJ,MAAMC,KAAKuJ,EAAQH,UAC9BK,EAAQhL,EAAOV,WAGrBgC,MAAMC,KAAKrB,EAAQyK,UAAUxE,QAAQ8E,IAEA,cAA/BA,EAAG3K,aAAaZ,EAAME,MAAsBoG,EAASkD,IAAI,EAAG,4BAA6B+B,GAE7F,MAAMC,EAAK5D,EAAM9D,IAAIzC,SAASrB,EAAME,IAAKqL,EAAG3K,aAAaZ,EAAME,KAAMkL,GAChEI,EAGOhB,EAAUgB,EAAG9H,UAAW6H,EAAG7H,aACrC4C,EAASkD,IAAI8B,EAAO,mBAAoBC,EAAIC,GAC5CD,EAAGE,YAAYD,EAAGE,WAAU,MAJ5BpF,EAASkD,IAAI8B,EAAO,mBAAoBC,GACxCA,EAAGI,YAQPN,EAAS5E,QAAQ,CAAC+E,EAAII,KACThE,EAAM9D,IAAIzC,SAASrB,EAAME,IAAKsL,EAAG5K,aAAaZ,EAAME,KAAMM,KAEnE8F,EAASkD,IAAI8B,EAAO,iBAAkBE,GACtChL,EAAQqL,OAAOL,EAAGE,WAAU,OAKhCL,EAAS5E,QAAQ,CAAC+E,EAAII,KACpB,MAAML,EAAK/K,EAAQyK,SAASW,GACxBL,EAAG3K,aAAaZ,EAAME,OAASsL,EAAG5K,aAAaZ,EAAME,MAAMqL,EAAGE,YAAYD,EAAGE,WAAU,UC/ClF,CACbnL,OAAM4G,QAAEA,EAAO6B,MAAEA,EAAK1C,SAAEA,IACtBtD,OAAOC,QAAQ+F,EAAMsB,SAClBP,OAAO,EAAE+B,EAAUrC,KACX7B,EAAMV,aAAaC,EAASsC,EAAQpE,OAASuC,EAAM9D,IAAIrB,YAAYqJ,IAE3ErF,QAAQ,EAAEqF,EAAUrC,MACnB,MAAMjJ,EAAUoH,EAAM9D,IAAIrB,YAAYqJ,GAEtC,IAAKtL,EAAS,OAEd,MAAM4C,EAAOqG,EAAQQ,SAEf8B,EAAQnE,EAAM9D,IAAIkI,YAAYxL,GAEpC,GAAKyL,EAAMd,WAAW3K,EAAS4C,GAA/B,CAEA,GAAI6I,EAAMjB,SAASxK,GAIjB,OAHA8F,EAASkD,IAAIlJ,EAAOV,WAAY,mBAAoB6J,EAAQpE,KAAM7E,GAClEyL,EAAMC,QAAQ,CAAE1L,QAAAA,EAAS4C,KAAAA,EAAMkD,SAAAA,EAAU0C,MAAAA,SACzCpB,EAAM9D,IAAIqI,aAAa3L,EAASuL,GAKlCvL,EAAQM,MAAMsL,QAAmB,KAAThJ,EAAc,OAAS,GAC/C5C,EAAQkD,UAAYN,EAEpBwE,EAAM9D,IAAIqI,aAAa3L,EAASuL,GAChCzF,EAASkD,IAAIlJ,EAAOV,WAAY,oBAAqB6J,EAAQpE,KAAM7E,UC/B5D,CACbD,MAAMsF,GAAMyE,QAAEA,EAAOjB,SAAEA,IACrB,MAAMgD,EAAW,IAAIC,iBAAiB,EAAEC,MACtCA,EAAOC,aAAa/F,QAAQxE,IAC1B,GAAIA,EAAIU,WAAaC,KAAK6J,aAAc,CACtC,MAAMC,EAAUzK,EAAIrB,aAAaN,EAAON,MAAMG,OACxCwM,EAAY1K,EAAIrB,aAAaN,EAAON,MAAMI,QAC5CsM,UAAgBpC,EAAQoC,GAExBC,IACFtD,EAASsD,GAAWlG,QAAQmG,IAC1BA,EAAK3K,IAAI4K,oBAAoBD,EAAKtD,UAAWsD,EAAKnD,kBAE7CJ,EAASsD,SAOxB,OADAN,EAASS,QAAQjH,EAAM,CAAEkH,YAAY,EAAMC,WAAW,EAAMC,SAAS,IAC9DZ,ICfX,MAAMa,EAAS,CACbC,KAAMvF,EAAMlD,aACZnE,KAAIgG,QACFA,EAAU,GAAEwC,SACZA,EAAQjD,KACRA,EAAO,GAAEC,QACTA,EAAU,GAAEqH,SACZA,EAAW,GAAEjN,MACbA,EAAQ,GAAEkN,MACVA,EAAQ,GAAEC,WACVA,GAAa1J,OAASA,OAAO0J,WAAa,MAAIC,MAC9CA,GAAQ,IAER,IAAKD,EAAY,MAAM,IAAIrI,MAAM,4CAEjC,MAAMqB,EAAWgH,EAAWlD,SACtBpB,EAAQ,CAAEsB,QAAS,GAAIjB,SAAU,IAGvC,OAFA/I,EAAOT,SAAS0N,GAET,CACLvE,MAAAA,EACA1C,SAAAA,EACA/F,aAAaiN,GAEX,MAAM3H,EAAO2H,EAAS7K,WAAaC,KAAK6J,aAAee,EAAW9M,SAAS4B,cAAckL,GAEzF,IAAK3H,EAAM,MAAM,IAAIZ,MAAM,mCAAmCuI,gDAGxDrI,QAAQsI,IAAIzK,OAAO0K,OAAON,IAChCpK,OAAOC,QAAQmK,GAAU3G,QAAQkH,OAAQjH,EAAMkH,KAC7CtH,EAASuH,gBAAgBnH,EAAMkH,aAAezI,cAAgByI,EAAMA,IAItE,MAAME,EAAaxH,EAASyH,QAAQhF,aAAoB5D,cAAgB4D,EAAWA,GAE7EnD,EAAQ,CACZC,KAAAA,EACAE,QAAAA,EACAD,KAAsB,mBAATA,EAAsBA,IAASA,GAG9C8B,EAAMoG,gBAAgB,CAAE1H,SAAAA,EAAUC,QAAAA,EAASX,MAAAA,IAC3CqI,EAAQC,SAAS,CAAE5H,SAAAA,EAAUyC,SAAAA,EAAUC,MAAAA,EAAOpD,MAAAA,IAE9CA,EAAME,KAAOqE,EAAUC,OAAOxE,EAAO+H,MAAAA,IACnCrH,EAASkD,IAAIlJ,EAAOV,WAAY,iBAAkBuH,GAClDgH,EAAS9D,MAAM,CAAElD,QAAAA,EAAS6B,MAAAA,EAAO1C,SAAAA,UAE3BsB,EAAM1C,WACZlC,OAAOC,QAAQ9C,GAAOsG,QAAQ,EAAEpB,EAAMsB,MAChCiB,EAAMV,aAAaC,EAAS,CAAC9B,KAAQsB,EAAGI,KAAKnB,EAAME,KAAM8B,EAAMd,aAAalB,EAAME,KAAMF,QAIhGwI,EAAQC,MAAMxI,EAAMmD,GACpB,MAAMhD,EAAU4B,EAAMd,aAAalB,EAAME,KAAMF,GAM/C,OAJIyH,EAAMiB,oBAAoBjB,EAAMiB,aAAavH,KAAKnB,EAAME,KAAME,GAClEH,EAAKnC,UAAYoK,EAAWlI,EAAME,MAC9BuH,EAAMkB,mBAAmBlB,EAAMkB,YAAYxH,KAAKnB,EAAME,KAAME,GAEzDA,aAOXpC,SAAQA,OAAOsJ,OAAStJ,OAAOsJ,QAAUA"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6e6d06b..6203d8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "re-bars", - "version": "0.0.1-beta.3.0.1", + "version": "0.0.1-beta.3.1.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -157,6 +157,15 @@ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, + "@types/fs-extra": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.1.tgz", + "integrity": "sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "http://localhost:4543/@types%2fglob/-/glob-7.1.1.tgz", @@ -175,9 +184,9 @@ "dev": true }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "http://localhost:4543/@types%2fistanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", + "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==", "dev": true }, "@types/minimatch": { @@ -204,14 +213,11 @@ "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", "dev": true }, - "access-log": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/access-log/-/access-log-0.3.9.tgz", - "integrity": "sha1-AcJpW6fn0y21KI7z8U5k1nGfOtE=", - "dev": true, - "requires": { - "strftime": "~0.6.2" - } + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "acorn": { "version": "7.1.1", @@ -250,9 +256,9 @@ "dev": true }, "aggregate-error": { - "version": "3.0.1", - "resolved": "http://localhost:4543/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { "clean-stack": "^2.0.0", @@ -427,66 +433,80 @@ "dev": true }, "ava": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/ava/-/ava-3.7.1.tgz", - "integrity": "sha512-UX7RSenUgFPhxe866doqOJy6tQZAXAVAU4yufYeBAcnEjnS/plIcG6lE2yGIqgjk5cIMpSi+sP4f6EsornlsuA==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.12.1.tgz", + "integrity": "sha512-cS41+X+UfrcPed+CIgne/YV/6eWxaUjHEPH+W8WvNSqWTWku5YitjZGE5cMHFuJxwHELdR541xTBRn8Uwi4PSw==", "dev": true, "requires": { "@concordance/react": "^2.0.0", + "acorn": "^8.0.1", + "acorn-walk": "^8.0.0", "ansi-styles": "^4.2.1", "arrgv": "^1.0.2", "arrify": "^2.0.1", - "chalk": "^4.0.0", - "chokidar": "^3.3.1", + "callsites": "^3.1.0", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", "chunkd": "^2.0.1", "ci-info": "^2.0.0", - "ci-parallel-vars": "^1.0.0", - "clean-stack": "^2.2.0", + "ci-parallel-vars": "^1.0.1", "clean-yaml-object": "^0.1.0", "cli-cursor": "^3.1.0", "cli-truncate": "^2.1.0", - "code-excerpt": "^2.1.1", + "code-excerpt": "^3.0.0", "common-path-prefix": "^3.0.0", - "concordance": "^4.0.0", + "concordance": "^5.0.1", "convert-source-map": "^1.7.0", "currently-unhandled": "^0.4.1", "debug": "^4.1.1", "del": "^5.1.0", - "emittery": "^0.6.0", + "emittery": "^0.7.1", "equal-length": "^1.0.0", "figures": "^3.2.0", - "globby": "^11.0.0", - "ignore-by-default": "^1.0.0", + "globby": "^11.0.1", + "ignore-by-default": "^2.0.0", "import-local": "^3.0.2", "indent-string": "^4.0.0", "is-error": "^2.2.2", - "is-plain-object": "^3.0.0", - "is-promise": "^2.1.0", - "lodash": "^4.17.15", - "matcher": "^2.1.0", + "is-plain-object": "^4.1.1", + "is-promise": "^4.0.0", + "lodash": "^4.17.20", + "matcher": "^3.0.0", "md5-hex": "^3.0.1", "mem": "^6.1.0", "ms": "^2.1.2", - "ora": "^4.0.3", + "ora": "^5.0.0", "p-map": "^4.0.0", "picomatch": "^2.2.2", "pkg-conf": "^3.1.0", "plur": "^4.0.0", - "pretty-ms": "^6.0.1", + "pretty-ms": "^7.0.0", "read-pkg": "^5.2.0", "resolve-cwd": "^3.0.0", "slash": "^3.0.0", - "source-map-support": "^0.5.16", - "stack-utils": "^2.0.1", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.2", "strip-ansi": "^6.0.0", "supertap": "^1.0.0", "temp-dir": "^2.0.0", "trim-off-newlines": "^1.0.1", - "update-notifier": "^4.1.0", + "update-notifier": "^4.1.1", "write-file-atomic": "^3.0.3", - "yargs": "^15.3.1" + "yargs": "^15.4.1" }, "dependencies": { + "acorn": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.1.tgz", + "integrity": "sha512-dmKn4pqZ29iQl2Pvze1zTrps2luvls2PBY//neO2WJ0s10B3AxJXshN+Ph7B4GrhfGhHXrl4dnUwyNNXQcnWGQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.0.0.tgz", + "integrity": "sha512-oZRad/3SMOI/pxbbmqyurIx7jHw1wZDcR9G44L8pUVFEomX/0dH89SrM1KaDXuv1NpzAXz6Op/Xu/Qd5XXzdEA==", + "dev": true + }, "ansi-styles": { "version": "4.2.1", "resolved": "http://localhost:4543/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -498,15 +518,31 @@ } }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "http://localhost:4543/color-convert/-/color-convert-2.0.1.tgz", @@ -537,6 +573,49 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "ignore-by-default": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", + "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", + "dev": true + }, + "is-plain-object": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", + "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "http://localhost:4543/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -547,18 +626,51 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "http://localhost:4543/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, + "update-notifier": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", + "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", + "dev": true, + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -571,17 +683,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "yargs-parser": "^18.1.2" } } } @@ -626,9 +728,9 @@ "dev": true }, "blueimp-md5": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.13.0.tgz", - "integrity": "sha512-lmp0m647R5e77ORduxLW5mISIDcvgJZa52vMBv5uVI3UmSWTQjkJsZVBfaFqQPw/QFogJwvY6e3Gl9nP+Loe+Q==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.18.0.tgz", + "integrity": "sha512-vE52okJvzsVWhcgUHOv+69OG3Mdg151xyn41aVQN/5W5S+S43qZhxECtYLAEHMSFWX6Mv5IZrzj3T5+JqXfj5Q==", "dev": true }, "boxen": { @@ -755,9 +857,9 @@ "dev": true }, "c8": { - "version": "7.1.0", - "resolved": "http://localhost:4543/c8/-/c8-7.1.0.tgz", - "integrity": "sha512-r4ba14DehwROz7Sm/JpwqL+s2FGGMiVmgnhAtYJ/jQcPpR7L+yEO3MUoQXHOFBetqd+mpTY5XiNY79QY6bYpnw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.1.2.tgz", + "integrity": "sha512-lCEwL9lbvWOQLxoLw8RF7PM8Cdj+rKxRp/PyWC9S8xASvYHRwXQ2gxzsNTgLhQM1Utc1YDAjzQYPQIxVEyelGg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", @@ -767,12 +869,12 @@ "furi": "^2.0.0", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-report": "^3.0.0", - "istanbul-reports": "^3.0.0", + "istanbul-reports": "^3.0.2", "rimraf": "^3.0.0", "test-exclude": "^6.0.0", "v8-to-istanbul": "^4.1.2", "yargs": "^15.0.0", - "yargs-parser": "^16.0.0" + "yargs-parser": "^18.0.0" }, "dependencies": { "rimraf": { @@ -783,16 +885,6 @@ "requires": { "glob": "^7.1.3" } - }, - "yargs-parser": { - "version": "16.1.0", - "resolved": "http://localhost:4543/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -892,9 +984,9 @@ "dev": true }, "ci-parallel-vars": { - "version": "1.0.0", - "resolved": "http://localhost:4543/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz", - "integrity": "sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", "dev": true }, "clean-stack": { @@ -909,12 +1001,6 @@ "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", "dev": true }, - "cleanse": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/cleanse/-/cleanse-0.0.3.tgz", - "integrity": "sha1-4S7UkQLSaOoBelykgDQG3I0jjAU=", - "dev": true - }, "cli-boxes": { "version": "2.2.0", "resolved": "http://localhost:4543/cli-boxes/-/cli-boxes-2.2.0.tgz", @@ -931,9 +1017,9 @@ } }, "cli-spinners": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", - "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", + "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==", "dev": true }, "cli-truncate": { @@ -1034,9 +1120,9 @@ } }, "code-excerpt": { - "version": "2.1.1", - "resolved": "http://localhost:4543/code-excerpt/-/code-excerpt-2.1.1.tgz", - "integrity": "sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", "dev": true, "requires": { "convert-to-spaces": "^1.0.1" @@ -1057,6 +1143,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colorette": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.0.tgz", + "integrity": "sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw==", + "dev": true + }, "colors": { "version": "1.4.0", "resolved": "http://localhost:4543/colors/-/colors-1.4.0.tgz", @@ -1092,37 +1184,25 @@ "dev": true }, "concordance": { - "version": "4.0.0", - "resolved": "http://localhost:4543/concordance/-/concordance-4.0.0.tgz", - "integrity": "sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.1.tgz", + "integrity": "sha512-TbNtInKVElgEBnJ1v2Xg+MFX2lvFLbmlv3EuSC5wTfCwpB8kC3w3mffF6cKuUhkn475Ym1f1I4qmuXzx2+uXpw==", "dev": true, "requires": { - "date-time": "^2.1.0", - "esutils": "^2.0.2", - "fast-diff": "^1.1.2", + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", "js-string-escape": "^1.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.flattendeep": "^4.4.0", - "lodash.islength": "^4.0.1", - "lodash.merge": "^4.6.1", - "md5-hex": "^2.0.0", - "semver": "^5.5.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", "well-known-symbols": "^2.0.0" }, "dependencies": { - "md5-hex": { - "version": "2.0.0", - "resolved": "http://localhost:4543/md5-hex/-/md5-hex-2.0.0.tgz", - "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", - "dev": true, - "requires": { - "md5-o-matic": "^0.1.1" - } - }, "semver": { - "version": "5.7.1", - "resolved": "http://localhost:4543/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } @@ -1261,9 +1341,9 @@ } }, "date-time": { - "version": "2.1.0", - "resolved": "http://localhost:4543/date-time/-/date-time-2.1.0.tgz", - "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", "dev": true, "requires": { "time-zone": "^1.0.0" @@ -1359,9 +1439,9 @@ } }, "ignore": { - "version": "5.1.4", - "resolved": "http://localhost:4543/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "p-map": { @@ -1444,15 +1524,6 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, - "easyreq": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/easyreq/-/easyreq-0.1.3.tgz", - "integrity": "sha1-uS2JSu8epIFaRBA3KNe2hVvdero=", - "dev": true, - "requires": { - "cleanse": "0.0.3" - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "http://localhost:4543/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1490,9 +1561,9 @@ } }, "emittery": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.6.0.tgz", - "integrity": "sha512-6EMRGr9KzYWp8DzHFZsKVZBsMO6QhAeHMeHND8rhyBNCHKMLpgW9tZv40bwN3rAIKRS5CxcK8oLRKUJSB9h7yQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", "dev": true }, "emoji-regex": { @@ -1651,7 +1722,7 @@ }, "esm": { "version": "3.2.25", - "resolved": "http://localhost:4543/esm/-/esm-3.2.25.tgz", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true }, @@ -1875,9 +1946,9 @@ }, "dependencies": { "cross-spawn": { - "version": "7.0.1", - "resolved": "http://localhost:4543/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -1934,6 +2005,17 @@ "mime-types": "^2.1.12" } }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "http://localhost:4543/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2035,9 +2117,9 @@ } }, "globby": { - "version": "11.0.0", - "resolved": "http://localhost:4543/globby/-/globby-11.0.0.tgz", - "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -2049,9 +2131,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.4", - "resolved": "http://localhost:4543/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } @@ -2162,12 +2244,6 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, - "he": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/he/-/he-0.4.1.tgz", - "integrity": "sha1-yGZnYU0t1xvHN6GXx2D7LuyKGSE=", - "dev": true - }, "hosted-git-info": { "version": "2.8.8", "resolved": "http://localhost:4543/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -2184,9 +2260,9 @@ } }, "html-escaper": { - "version": "2.0.0", - "resolved": "http://localhost:4543/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "http-cache-semantics": { @@ -2235,18 +2311,6 @@ "sshpk": "^1.7.0" } }, - "httpserver": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/httpserver/-/httpserver-0.3.0.tgz", - "integrity": "sha1-6a6usNLUCy74Eghr0M+FUFPnCVA=", - "dev": true, - "requires": { - "access-log": "~0.3.9", - "latest": "~0.2.0", - "posix-getopt": "~1.2.0", - "static-route": "~0.1.2" - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "http://localhost:4543/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2544,9 +2608,9 @@ } }, "istanbul-reports": { - "version": "3.0.0", - "resolved": "http://localhost:4543/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -2656,6 +2720,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "http://localhost:4543/json-schema/-/json-schema-0.2.3.tgz", @@ -2680,6 +2750,15 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsprim": { "version": "1.4.1", "resolved": "http://localhost:4543/jsprim/-/jsprim-1.4.1.tgz", @@ -2707,15 +2786,6 @@ "json-buffer": "3.0.0" } }, - "latest": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/latest/-/latest-0.2.0.tgz", - "integrity": "sha1-6kfrj0srsM+RcW76qJbC4WI3WHs=", - "dev": true, - "requires": { - "npm": "^2.5.1" - } - }, "latest-version": { "version": "5.1.0", "resolved": "http://localhost:4543/latest-version/-/latest-version-5.1.0.tgz", @@ -2772,21 +2842,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "http://localhost:4543/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "http://localhost:4543/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "http://localhost:4543/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, "lodash.get": { @@ -2795,12 +2853,6 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.islength": { - "version": "4.0.1", - "resolved": "http://localhost:4543/lodash.islength/-/lodash.islength-4.0.1.tgz", - "integrity": "sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc=", - "dev": true - }, "lodash.merge": { "version": "4.6.2", "resolved": "http://localhost:4543/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2814,12 +2866,64 @@ "dev": true }, "log-symbols": { - "version": "3.0.0", - "resolved": "http://localhost:4543/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.4.2" + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "lowercase-keys": { @@ -2862,18 +2966,18 @@ "dev": true }, "matcher": { - "version": "2.1.0", - "resolved": "http://localhost:4543/matcher/-/matcher-2.1.0.tgz", - "integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "escape-string-regexp": "^4.0.0" }, "dependencies": { "escape-string-regexp": { - "version": "2.0.0", - "resolved": "http://localhost:4543/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true } } @@ -2887,16 +2991,10 @@ "blueimp-md5": "^2.10.0" } }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "http://localhost:4543/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true - }, "mem": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz", - "integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", + "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", "dev": true, "requires": { "map-age-cleaner": "^0.1.3", @@ -2904,9 +3002,9 @@ }, "dependencies": { "mimic-fn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz", - "integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "dev": true } } @@ -2933,12 +3031,6 @@ "picomatch": "^2.0.5" } }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", - "dev": true - }, "mime-db": { "version": "1.43.0", "resolved": "http://localhost:4543/mime-db/-/mime-db-1.43.0.tgz", @@ -3033,6 +3125,41 @@ "path-to-regexp": "^1.7.0" } }, + "nodemon": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", + "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "http://localhost:4543/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -3065,1799 +3192,6 @@ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", "dev": true }, - "npm": { - "version": "2.15.12", - "resolved": "https://registry.npmjs.org/npm/-/npm-2.15.12.tgz", - "integrity": "sha1-33w+1aJ3w/nUtdgZsFMR0QogCuY=", - "dev": true, - "requires": { - "abbrev": "~1.0.9", - "ansi": "~0.3.1", - "ansi-regex": "*", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "archy": "~1.0.0", - "async-some": "~1.0.2", - "block-stream": "0.0.9", - "char-spinner": "~1.0.1", - "chmodr": "~1.0.2", - "chownr": "~1.0.1", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.10", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "fs-vacuum": "~1.2.9", - "fs-write-stream-atomic": "~1.0.8", - "fstream": "~1.0.10", - "fstream-npm": "~1.1.1", - "github-url-from-git": "~1.4.0", - "github-url-from-username-repo": "~1.0.2", - "glob": "~7.0.6", - "graceful-fs": "~4.1.6", - "hosted-git-info": "~2.1.5", - "imurmurhash": "*", - "inflight": "~1.0.4", - "inherits": "~2.0.3", - "ini": "~1.3.4", - "init-package-json": "~1.9.4", - "lockfile": "~1.0.1", - "lru-cache": "~4.0.1", - "minimatch": "~3.0.3", - "mkdirp": "~0.5.1", - "node-gyp": "~3.6.0", - "nopt": "~3.0.6", - "normalize-git-url": "~3.0.2", - "normalize-package-data": "~2.3.5", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~1.0.7", - "npm-package-arg": "~4.1.0", - "npm-registry-client": "~7.2.1", - "npm-user-validate": "~0.1.5", - "npmlog": "~2.0.4", - "once": "~1.4.0", - "opener": "~1.4.1", - "osenv": "~0.1.3", - "path-is-inside": "~1.0.0", - "read": "~1.0.7", - "read-installed": "~4.0.3", - "read-package-json": "~2.0.4", - "readable-stream": "~2.1.5", - "realize-package-specifier": "~3.0.1", - "request": "~2.74.0", - "retry": "~0.10.0", - "rimraf": "~2.5.4", - "semver": "~5.1.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.0", - "spdx-license-ids": "~1.2.2", - "strip-ansi": "~3.0.1", - "tar": "~2.2.1", - "text-table": "~0.2.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "validate-npm-package-license": "~3.0.1", - "validate-npm-package-name": "~2.2.2", - "which": "~1.2.11", - "wrappy": "~1.0.2", - "write-file-atomic": "~1.1.4" - }, - "dependencies": { - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", - "dev": true - }, - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", - "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=", - "dev": true - }, - "ansicolors": { - "version": "0.3.2", - "dev": true - }, - "ansistyles": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz", - "dev": true - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "async-some": { - "version": "1.0.2", - "integrity": "sha1-TYqBYg1ZWHkbW5j4AtMgd3bpVQk=", - "dev": true, - "requires": { - "dezalgo": "^1.0.2" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "char-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz", - "integrity": "sha1-5upnvSR+EHESmDt6sEee02KAAIE=", - "dev": true - }, - "chmodr": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz", - "integrity": "sha1-BGYrky0PAuxm3qorDqQoEZaOPrk=", - "dev": true - }, - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true - }, - "cmd-shim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", - "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "columnify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", - "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", - "dev": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - }, - "dependencies": { - "wcwidth": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.0.tgz", - "integrity": "sha1-AtBZ/3qPx0Hg9rXaHmmytA2uym8=", - "dev": true, - "requires": { - "defaults": "^1.0.0" - }, - "dependencies": { - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - }, - "dependencies": { - "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", - "dev": true - } - } - } - } - } - } - }, - "config-chain": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.10.tgz", - "integrity": "sha1-f8OD3g/MhNcRy0Zb0XZXnK1hI0Y=", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - }, - "dependencies": { - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - } - } - }, - "dezalgo": { - "version": "1.0.3", - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", - "dev": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - }, - "dependencies": { - "asap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.3.tgz", - "integrity": "sha1-H8HRVk7hFiDfym1nAphQkT+fRnk=", - "dev": true - } - } - }, - "editor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz", - "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=", - "dev": true - }, - "fs-vacuum": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.9.tgz", - "integrity": "sha1-T5AZOrjqAokJlbzU6ARlml02ay0=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz", - "integrity": "sha1-5Jqt3yiPh9Rv+eiC8hahOrxAd4s=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - } - } - }, - "fstream": { - "version": "1.0.10", - "integrity": "sha1-YE6Kkv4m/9n2+uMDmdSYThqyKCI=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-npm": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fstream-npm/-/fstream-npm-1.1.1.tgz", - "integrity": "sha1-a5F122I5qD2CCeIyQmxJTbspaQw=", - "dev": true, - "requires": { - "fstream-ignore": "^1.0.0", - "inherits": "2" - }, - "dependencies": { - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "dev": true, - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - } - } - }, - "github-url-from-git": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.4.0.tgz", - "integrity": "sha1-KF5rUggZABveEoZ0cEN55P8D4N4=", - "dev": true - }, - "github-url-from-username-repo": { - "version": "1.0.2", - "integrity": "sha1-fdeTMNKr5pwQws73lxTJchV5Hfo=", - "dev": true - }, - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", - "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha1-UUw4dysxvuLgi+3CGgrrOr9UwZ4=", - "dev": true - }, - "hosted-git-info": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", - "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", - "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "dev": true - }, - "init-package-json": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.9.4.tgz", - "integrity": "sha1-tAU9C0Dwz4QqQZZpN8s9wPU06FY=", - "dev": true, - "requires": { - "glob": "^6.0.0", - "npm-package-arg": "^4.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^2.0.1" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", - "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=", - "dev": true - } - } - }, - "promzard": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", - "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", - "dev": true, - "requires": { - "read": "1" - } - } - } - }, - "lockfile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz", - "integrity": "sha1-nTU+z+P1TRULtX+J1RdGk1o5xPU=", - "dev": true - }, - "lru-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", - "integrity": "sha1-E0OVXtry432bnn7nJB4nxLn7cr4=", - "dev": true, - "requires": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - }, - "dependencies": { - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "yallist": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", - "integrity": "sha1-MGxUODXwnuGkyyO3vOmrNByRzdQ=", - "dev": true - } - } - }, - "minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", - "dev": true, - "requires": { - "brace-expansion": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", - "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", - "dev": true, - "requires": { - "balanced-match": "^0.4.1", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - } - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "node-gyp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.0.tgz", - "integrity": "sha1-dHT2OjoFARYd2gtjQfAi8UxCP6Y=", - "dev": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - } - } - }, - "nopt": { - "version": "3.0.6", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-git-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/normalize-git-url/-/normalize-git-url-3.0.2.tgz", - "integrity": "sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q=", - "dev": true - }, - "normalize-package-data": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", - "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - }, - "dependencies": { - "builtin-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.0.tgz", - "integrity": "sha1-EFOVX9mUpXRuUl5Kxxe4HK8HSRw=", - "dev": true - } - } - } - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz", - "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=", - "dev": true - }, - "npm-install-checks": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-1.0.7.tgz", - "integrity": "sha1-bZGu2grJaAHx7Xqt7hFqbAoIalc=", - "dev": true, - "requires": { - "npmlog": "0.1 || 1 || 2", - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-package-arg": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-4.1.0.tgz", - "integrity": "sha1-LgFfisAHN8uX+ZfJy/BZ9Cp0Un0=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "semver": "4 || 5" - } - }, - "npm-registry-client": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-7.2.1.tgz", - "integrity": "sha1-x5ImawiMwxP4Ul5+NSSGJscj23U=", - "dev": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0", - "npmlog": "~2.0.0 || ~3.1.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - } - } - }, - "retry": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz", - "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=", - "dev": true - } - } - }, - "npm-user-validate": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-0.1.5.tgz", - "integrity": "sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs=", - "dev": true - }, - "npmlog": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", - "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", - "dev": true, - "requires": { - "ansi": "~0.3.1", - "are-we-there-yet": "~1.1.2", - "gauge": "~1.2.5" - }, - "dependencies": { - "are-we-there-yet": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz", - "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.0 || ^1.1.13" - }, - "dependencies": { - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - } - } - }, - "gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", - "dev": true, - "requires": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - }, - "dependencies": { - "has-unicode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.0.tgz", - "integrity": "sha1-o82Wwwe6QdVZxaLuQIwSoRxMLsM=", - "dev": true - }, - "lodash._baseslice": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/lodash._baseslice/-/lodash._baseslice-4.0.0.tgz", - "integrity": "sha1-9c4d+YKUjsr/Y/IjhTQVt7l2NwQ=", - "dev": true - }, - "lodash._basetostring": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz", - "integrity": "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8=", - "dev": true - }, - "lodash.pad": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.4.0.tgz", - "integrity": "sha1-+qON8mwKaexQhqgiRslY4VDcsas=", - "dev": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.padend": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.5.0.tgz", - "integrity": "sha1-oonpN37i5t6Lp/EfOo6zJgcLdhk=", - "dev": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.padstart": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.5.0.tgz", - "integrity": "sha1-PqGQ9nNIQcM2TSedEeBWcmtgp5o=", - "dev": true, - "requires": { - "lodash._baseslice": "~4.0.0", - "lodash._basetostring": "~4.12.0", - "lodash.tostring": "^4.0.0" - } - }, - "lodash.tostring": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.4.tgz", - "integrity": "sha1-Vgwn0fjq3eA8LM4Zj+9cAx2CmPs=", - "dev": true - } - } - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.1.tgz", - "integrity": "sha1-iXWQrNGu0zEbcDtYvMtNQ/VvKJU=", - "dev": true - }, - "osenv": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", - "integrity": "sha1-g88FxtZFj8TVrGNi6jJdkvJ1Qhc=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - }, - "dependencies": { - "os-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.0.tgz", - "integrity": "sha1-43B4vGG1hpBjBTiXJX457BJhtwI=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", - "integrity": "sha1-6bQjoe2vR5iCVi6S7XHXdDoHG24=", - "dev": true - } - } - }, - "path-is-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.1.tgz", - "dev": true - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - }, - "dependencies": { - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - } - } - }, - "read-installed": { - "version": "4.0.3", - "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - }, - "dependencies": { - "debuglog": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", - "dev": true - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=", - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "util-extend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.1.tgz", - "integrity": "sha1-u3A7eUgCk93Nz7PGqf6iD0g0Fbw=", - "dev": true - } - } - }, - "read-package-json": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.4.tgz", - "integrity": "sha1-Ye0bIlbqQ42ACIlQkL6EuOeZyFM=", - "dev": true, - "requires": { - "glob": "^6.0.0", - "graceful-fs": "^4.1.2", - "json-parse-helpfulerror": "^1.0.2", - "normalize-package-data": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", - "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=", - "dev": true - } - } - }, - "json-parse-helpfulerror": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", - "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", - "dev": true, - "requires": { - "jju": "^1.1.0" - }, - "dependencies": { - "jju": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz", - "integrity": "sha1-2t2e8BkkvHKLA/L3l5vb1i96Kqo=", - "dev": true - } - } - } - } - }, - "readable-stream": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", - "dev": true, - "requires": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - } - } - }, - "realize-package-specifier": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/realize-package-specifier/-/realize-package-specifier-3.0.1.tgz", - "integrity": "sha1-/eMukmRI44+ZM02Vt7CNUeOpjZ8=", - "dev": true, - "requires": { - "dezalgo": "^1.0.1", - "npm-package-arg": "^4.0.0" - } - }, - "request": { - "version": "2.74.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz", - "integrity": "sha1-dpPKdou7DqXIzgjAhKRe+gW4kqs=", - "dev": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~1.0.0-rc4", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" - }, - "dependencies": { - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz", - "integrity": "sha1-/efVKSRm0jDl7g9OA42d+qsI/GE=", - "dev": true - }, - "bl": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", - "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", - "dev": true, - "requires": { - "readable-stream": "~2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - } - } - } - } - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - }, - "dependencies": { - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - } - } - }, - "extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", - "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "1.0.0-rc4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", - "integrity": "sha1-BaxrwiIntD5EYfSIFhVUaZ1Pi14=", - "dev": true, - "requires": { - "async": "^1.5.2", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.10" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - }, - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - } - } - }, - "is-my-json-valid": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz", - "integrity": "sha1-1Vd4qC/rawlj/0vhEdXRaE6JBwc=", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "jsonpointer": "2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - }, - "dependencies": { - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - } - } - }, - "jsonpointer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz", - "integrity": "sha1-OvHdIP6FRjkQ1GmjheMwF9KgMNk=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - } - } - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - } - } - } - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - }, - "dependencies": { - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.x.x" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - } - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "jsprim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz", - "integrity": "sha1-zi4b74NSBLTzCZkoxgL4tq5hVlA=", - "dev": true, - "requires": { - "extsprintf": "1.0.2", - "json-schema": "0.2.2", - "verror": "1.3.6" - }, - "dependencies": { - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", - "dev": true - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha1-UDVPGfYDkXxpX3C4Wvp3w7DyNQY=", - "dev": true - }, - "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", - "dev": true, - "requires": { - "extsprintf": "1.0.2" - } - } - } - }, - "sshpk": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.9.2.tgz", - "integrity": "sha1-O0E1G7rVw03fS9gRmTfv7jGkZ2U=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jodid25519": "^1.0.0", - "jsbn": "~0.1.0", - "tweetnacl": "~0.13.0" - }, - "dependencies": { - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "dashdash": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", - "integrity": "sha1-KeSGxUGL8PNWA0qZPVFoajPoQUE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "getpass": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", - "integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "jodid25519": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", - "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "jsbn": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", - "integrity": "sha1-ZQmH2g3XT06/WhE3eiqi0nPpff0=", - "dev": true, - "optional": true - }, - "tweetnacl": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz", - "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y=", - "dev": true, - "optional": true - } - } - } - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "mime-types": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", - "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", - "dev": true, - "requires": { - "mime-db": "~1.23.0" - }, - "dependencies": { - "mime-db": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", - "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=", - "dev": true - } - } - }, - "node-uuid": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", - "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "qs": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", - "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=", - "dev": true - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", - "integrity": "sha1-mcd9+7fYBCSeiimdTLD9gf7wg/0=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - } - } - }, - "retry": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz", - "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=", - "dev": true - }, - "rimraf": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "semver": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", - "integrity": "sha1-hfLPhVBGXE3wAM99hvawVBBqueU=", - "dev": true - }, - "sha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sha/-/sha-2.0.1.tgz", - "integrity": "sha1-YDCCL70smCOUn49y7WQR7lzyWq4=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", - "integrity": "sha1-vsgb6ujPRVFovC5bKzH1vPrtmxs=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "process-nextick-args": "~1.0.0", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", - "integrity": "sha1-4nLu2CXV6fTqdNjXOx/jEcO+tjA=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", - "integrity": "sha1-NVaj0TxMaqeYPX4kJUeBlxmbeIE=", - "dev": true - } - } - } - } - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "sorted-object": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.0.tgz", - "integrity": "sha1-HP6pgWCQR9gEOAekkKnZmzF/r38=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "tar": { - "version": "2.2.1", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "dev": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "text-table": { - "version": "0.2.0", - "dev": true - }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", - "dev": true - }, - "umask": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz", - "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" - }, - "dependencies": { - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "^1.0.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.2.tgz", - "integrity": "sha1-1SsUtelnB3FECvIlvLVjEirEUvY=", - "dev": true, - "requires": { - "spdx-exceptions": "^1.0.4", - "spdx-license-ids": "^1.0.0" - }, - "dependencies": { - "spdx-exceptions": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-1.0.4.tgz", - "integrity": "sha1-IguEI5EZrpBFqJLbgag/TOFvgP0=", - "dev": true - } - } - } - } - }, - "validate-npm-package-name": { - "version": "2.2.2", - "integrity": "sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU=", - "dev": true, - "requires": { - "builtins": "0.0.7" - }, - "dependencies": { - "builtins": { - "version": "0.0.7", - "dev": true - } - } - }, - "which": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.11.tgz", - "integrity": "sha1-yLLu6muMFln6fB3U/aq+lTPcXos=", - "dev": true, - "requires": { - "isexe": "^1.1.1" - }, - "dependencies": { - "isexe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", - "integrity": "sha1-NvPiLmB1CSD15yQaR2qMakInWtA=", - "dev": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "1.1.4", - "integrity": "sha1-sfUtwujcDjywTRh6JfdYo4qQyjs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" - } - } - } - }, "nwsapi": { "version": "2.2.0", "resolved": "http://localhost:4543/nwsapi/-/nwsapi-2.2.0.tgz", @@ -4909,16 +3243,16 @@ } }, "ora": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", - "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz", + "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==", "dev": true, "requires": { - "chalk": "^3.0.0", + "chalk": "^4.1.0", "cli-cursor": "^3.1.0", - "cli-spinners": "^2.2.0", + "cli-spinners": "^2.4.0", "is-interactive": "^1.0.0", - "log-symbols": "^3.0.0", + "log-symbols": "^4.0.0", "mute-stream": "0.0.8", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" @@ -4935,9 +3269,9 @@ } }, "chalk": { - "version": "3.0.0", - "resolved": "http://localhost:4543/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -4975,9 +3309,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "http://localhost:4543/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -5228,12 +3562,6 @@ } } }, - "posix-getopt": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/posix-getopt/-/posix-getopt-1.2.0.tgz", - "integrity": "sha1-Su7rfa3mb8qKk2XdqfawBXQctiE=", - "dev": true - }, "prelude-ls": { "version": "1.1.2", "resolved": "http://localhost:4543/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -5262,9 +3590,9 @@ } }, "pretty-ms": { - "version": "6.0.1", - "resolved": "http://localhost:4543/pretty-ms/-/pretty-ms-6.0.1.tgz", - "integrity": "sha512-ke4njoVmlotekHlHyCZ3wI/c5AMT8peuHs8rKJqekj/oR5G8lND2dVpicFlUz5cbZgE290vvkMuDwfj/OcW1kw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", + "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", "dev": true, "requires": { "parse-ms": "^2.1.0" @@ -5282,6 +3610,12 @@ "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", "dev": true }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "http://localhost:4543/pump/-/pump-3.0.0.tgz", @@ -5346,14 +3680,14 @@ }, "dependencies": { "parse-json": { - "version": "5.0.0", - "resolved": "http://localhost:4543/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -5555,6 +3889,43 @@ "acorn": "^7.1.0" } }, + "rollup-plugin-copy": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.3.0.tgz", + "integrity": "sha512-euDjCUSBXZa06nqnwCNADbkAcYDfzwowfZQkto9K/TFhiH+QG7I4PUsEMwM9tDgomGWJc//z7KLW8t+tZwxADA==", + "dev": true, + "requires": { + "@types/fs-extra": "^8.0.1", + "colorette": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "10.0.1", + "is-plain-object": "^3.0.0" + }, + "dependencies": { + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, "rollup-plugin-filesize": { "version": "6.2.1", "resolved": "http://localhost:4543/rollup-plugin-filesize/-/rollup-plugin-filesize-6.2.1.tgz", @@ -5827,9 +4198,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "http://localhost:4543/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -5843,9 +4214,9 @@ "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "http://localhost:4543/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -5853,9 +4224,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "http://localhost:4543/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", "dev": true }, "sprintf-js": { @@ -5882,9 +4253,9 @@ } }, "stack-utils": { - "version": "2.0.1", - "resolved": "http://localhost:4543/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-BvBTnHGm8boe+HiJFqP19ywEsGlfQAKqW78pbfvUuzCbUuxPPUyLrH5dYFY+Xn9IpLY3b5ZmMcl8jAqXB4wddg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -5898,29 +4269,12 @@ } } }, - "static-route": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-route/-/static-route-0.1.2.tgz", - "integrity": "sha1-FpojTFnxFOvZAWNuULsgvEW2aSQ=", - "dev": true, - "requires": { - "easyreq": "~0.1.0", - "he": "~0.4.1", - "mime": "~1.2.9" - } - }, "stealthy-require": { "version": "1.1.1", "resolved": "http://localhost:4543/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, - "strftime": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.6.2.tgz", - "integrity": "sha1-2kwSBzzr7jzWD0ghlAzCexnTSKE=", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "http://localhost:4543/string-width/-/string-width-4.2.0.tgz", @@ -6195,6 +4549,26 @@ "is-number": "^7.0.0" } }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "http://localhost:4543/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -6282,6 +4656,32 @@ "source-map": "~0.6.1" } }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -6300,6 +4700,12 @@ "crypto-random-string": "^2.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "update-notifier": { "version": "4.1.0", "resolved": "http://localhost:4543/update-notifier/-/update-notifier-4.1.0.tgz", @@ -6416,9 +4822,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "4.1.2", - "resolved": "http://localhost:4543/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz", - "integrity": "sha512-G9R+Hpw0ITAmPSr47lSlc5A1uekSYzXxTMlFxso2xoffwo4jQnzbv1p9yXIinO8UMZKfAFewaCHwWvnH4Jb4Ug==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -6669,9 +5075,9 @@ "dev": true }, "yargs": { - "version": "15.2.0", - "resolved": "http://localhost:4543/yargs/-/yargs-15.2.0.tgz", - "integrity": "sha512-E+o8C37U+M7N15rBJVxr0MoInp+O7XNhMqveSGWA5uhddqs8qtkZ+uvT9FI32QML0SKidXdDONr40Xe3tDO9FA==", + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -6684,13 +5090,13 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^17.1.0" + "yargs-parser": "^18.1.1" } }, "yargs-parser": { - "version": "17.1.0", - "resolved": "http://localhost:4543/yargs-parser/-/yargs-parser-17.1.0.tgz", - "integrity": "sha512-67zLl4/kWtp9eyVuxX+fHZ2Ey4ySWh0awDJlk/EtT0vzspsXbzrFsh76WjYSP3L++zhSwHQRUE3MCBe754RuEg==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index 450e983..0d77a1c 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,12 @@ "license": "MIT", "dependencies": {}, "devDependencies": { - "ava": "3.7.1", + "ava": "3.12.1", "browser-env": "^3.3.0", "c8": "7.1.2", "eslint": "^6.7.2", "eslint-config-prettier": "^6.7.0", "eslint-plugin-prettier": "^3.1.1", - "esm": "^3.2.25", "handlebars": "4.7.4", "http-server": "0.12.3", "marked": "0.8.2", diff --git a/rollup.config.js b/rollup.config.js index 7a00c5a..8b1990c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,12 +1,12 @@ import { terser } from "rollup-plugin-terser"; -// import strip from "rollup-plugin-strip"; +import strip from "rollup-plugin-strip"; import filesize from "rollup-plugin-filesize"; import gzipPlugin from "rollup-plugin-gzip"; import copy from "rollup-plugin-copy"; export default [ { - input: "src/app.js", + input: "src/index.js", output: [ { file: "dist/re-bars.umd.js", format: "umd", name: "ReBars" }, { @@ -30,10 +30,10 @@ export default [ }, ], - // plugins: [strip()], + plugins: [strip()], }, { - input: "src/app.js", + input: "src/index.js", output: [ { file: "dist/re-bars.esm.js", format: "module", name: "ReBars" }, { @@ -45,6 +45,6 @@ export default [ }, ], - // plugins: [strip()], + plugins: [strip()], }, ]; diff --git a/src/helpers.js b/src/helpers.js index 401df6b..af4ce98 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -15,6 +15,11 @@ export default { return new instance.SafeString(condition ? string : ""); }); + instance.registerHelper("concat", function(...args) { + args.pop(); + return new instance.SafeString(args.join("")); + }); + instance.registerHelper("on", function(...args) { const { hash } = args.pop(); const id = Utils.randomId(); @@ -45,6 +50,7 @@ export default { instance.registerHelper("bind", function(...args) { const { hash } = args.pop(); + const [forceValue] = args; const tplScope = this; const id = Utils.randomId(); @@ -56,8 +62,11 @@ export default { Object.entries(hash).forEach(([eventType, path]) => { function handler(event) { + let value = event.target.value; + value = value === "" ? null : value; + try { - Utils.setPath(tplScope, path, event.target.value || null); + Utils.setPath(tplScope, path, forceValue || value); } catch (err) { instance.log(3, `ReBars: could not set path ${path}`, $el); } diff --git a/src/app.js b/src/index.js similarity index 86% rename from src/app.js rename to src/index.js index e251937..10e25e6 100644 --- a/src/app.js +++ b/src/index.js @@ -18,18 +18,20 @@ const ReBars = { Handlebars = window ? window.Handlebars : null, trace = false, }) { - const instance = Handlebars.create(); - - const store = { renders: {}, handlers: {} }; if (!Handlebars) throw new Error("ReBars: needs Handlebars in order to run"); + const instance = Handlebars.create(); + const store = { renders: {}, handlers: {} }; Config.setTrace(trace); return { store, instance, async render(selector) { - const $app = document.querySelector(selector); + // takes an element or a selector + const $app = selector.nodeType === Node.ELEMENT_NODE ? selector : document.querySelector(selector); + + if (!$app) throw new Error(`ReBars: document.querySelector("${selector}") could not be found on the document`); // have to make sure they are resolved first await Promise.all(Object.values(partials)); @@ -40,13 +42,10 @@ const ReBars = { // must be compiled after the partials const templateFn = instance.compile(template instanceof Promise ? await template : template); - if (!$app) - return instance.log(3, `ReBars: document.querySelector("${selector}") could not be found on the document`); - const scope = { $app, methods, - data, + data: typeof data === "function" ? data() : data, }; Utils.registerHelpers({ instance, helpers, scope }); @@ -68,6 +67,8 @@ const ReBars = { if (hooks.beforeRender) await hooks.beforeRender.call(scope.data, context); $app.innerHTML = templateFn(scope.data); if (hooks.afterRender) await hooks.afterRender.call(scope.data, context); + + return context; }, }; }, diff --git a/src/utils/dom.js b/src/utils/dom.js index 1e32a66..72276b8 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -19,7 +19,7 @@ export default { restoreState($target, activeRef) { if (!activeRef) return; - const $input = this.findRef($target, activeRef.ref); + const $input = this.findAttr(attrs.ref, activeRef.ref, $target); if (!$input) return; $input.focus(); @@ -48,15 +48,11 @@ export default { // use this in place of all the others that are repeated eventually... findAttr(attr, val, $target = null) { const $container = $target || document; - if ($container.getAttribute(attr) === val) return $container; + // check top level + if ($target && $target.getAttribute(attr) === val) return $target; return $container.querySelector(`[${attr}="${val}"]`); }, - findRef: ($target, ref) => { - if ($target.getAttribute(attrs.ref) === ref) return $target; - return $target.querySelector(`[${attrs.ref}="${ref}"]`); - }, - findMethod: id => document.querySelector(`[${attrs.method}="${id}"]`), findWatcher: id => document.querySelector(`[${attrs.watch}="${id}"]`), isTextNode: $el => $el.nodeType === Node.TEXT_NODE, diff --git a/test/_old/app.spec.js b/test/_old/app.spec.js deleted file mode 100644 index 8375d5e..0000000 --- a/test/_old/app.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import test from "ava"; -import ReBars from "../src/index.js"; -import Handlebars from "handlebars"; -import Msg from "../src/Msg.js"; -import Utils from "../src/utils/index.js"; -import Component from "../src/component.js"; -import sinon from "sinon"; - -test.beforeEach(t => { - window.Handlebars = Handlebars; - t.context.$el = document.createElement("div"); - t.context.root = {}; - document.body.append(t.context.$el); - - t.context.app = { - $el: t.context.$el, - root: t.context.root, - }; - - t.context.renderStub = sinon.stub(); - t.context.instanceStub = sinon.stub().returns({ render: t.context.renderStub }); - - sinon.stub(Component, "register").returns({ - instance: t.context.instanceStub, - }); -}); - -test.afterEach.always(t => { - t.context.$el.remove(); - sinon.restore(); -}); - -test.serial("ReBars is a function", t => { - t.is(typeof ReBars.app, "function"); -}); - -test.serial("calls utils random id", t => { - sinon.stub(Utils, "randomId").returns("rando"); - const { id } = ReBars.app(t.context.app); - t.is(id, "rando"); - t.is(Utils.randomId.called, true); -}); - -test.serial("defines vars on window", t => { - ReBars.app(t.context.app); - t.is(typeof window.ReBars, "object"); - t.is(typeof window.ReBars.handlers, "object"); - t.is(typeof window.ReBars.apps, "object"); - t.is(window.rbs, window.ReBars); -}); - -test.serial("throws if element not in document", t => { - t.context.app.$el = document.createElement("div"); - const error = t.throws(() => ReBars.app(t.context.app)); - t.is(error.message, Msg.messages.noEl()); -}); - -test.serial("can create an app", t => { - ReBars.app(t.context.app); - t.is(Component.register.lastCall.args[2], t.context.root); - t.is(t.context.instanceStub.called, true); - t.is(t.context.renderStub.called, true); -}); - -test.serial("returns storage", t => { - const { storage, id } = ReBars.app(t.context.app); - t.is(typeof storage.inst, "object"); - t.is(typeof storage.cDefs, "object"); - t.is(typeof id, "string"); -}); - -test.serial("adds handlers", t => { - ReBars.app(t.context.app); - t.is(typeof window.rbs.handlers.bound, "function"); - t.is(typeof window.rbs.handlers.trigger, "function"); -}); - -test.serial("storage is stored on window", t => { - const { storage, id } = ReBars.app(t.context.app); - t.is(storage, window.rbs.apps[id]); -}); - -test.serial("needs Handlebars in order to run", t => { - delete window.Handlebars; - const error = t.throws(() => ReBars.app(t.context.app)); - t.is(error.message, Msg.messages.noHbs()); -}); diff --git a/test/_old/component-errors.spec.js b/test/_old/component-errors.spec.js deleted file mode 100644 index a1bf169..0000000 --- a/test/_old/component-errors.spec.js +++ /dev/null @@ -1,89 +0,0 @@ -import test from "ava"; -import sinon from "sinon"; -import ReBars from "../src/index.js"; -import Component from "../src/component.js"; -import Handlebars from "handlebars"; -import Msg from "../src/Msg.js"; - -test.beforeEach(t => { - window.Handlebars = Handlebars; - t.context.$el = document.createElement("div"); - document.body.append(t.context.$el); - - const { id } = ReBars.app({ - $el: t.context.$el, - root: { - name: "tester", - template: "

{{ name }}

", - }, - }); - - t.context.def = { - template: "

", - name: "test", - data: () => ({}), - }; - - t.context.id = id; -}); - -test.afterEach.always(t => { - t.context.$el.remove(); - sinon.restore(); -}); - -test("makes you add a name", t => { - delete t.context.def.name; - const error = t.throws(() => Component.register(t.context.id, Handlebars, t.context.def)); - t.is(error.message, Msg.messages.noName({})); -}); - -test("throws error if child components have no name", t => { - t.context.def.components = [{ prop: "val" }]; - const error = t.throws(() => Component.register(t.context.id, Handlebars, t.context.def)); - t.is(error.message, Msg.messages.noName(t.context.def)); -}); - -test("throws error if no root node", t => { - t.context.def.template = ""; - const error = t.throws(() => - Component.register(t.context.id, Handlebars, t.context.def) - .instance() - .render() - ); - t.is(error.message, Msg.messages.oneRoot(t.context.def)); -}); - -test("throws error if more than one root node", t => { - t.context.def.template = "
"; - const error = t.throws(() => - Component.register(t.context.id, Handlebars, t.context.def) - .instance() - .render() - ); - t.is(error.message, Msg.messages.oneRoot(t.context.def)); -}); - -test("throws error if root node is a watch", t => { - t.context.def.template = "{{#watch}}{{/watch}}"; - const error = t.throws(() => - Component.register(t.context.id, Handlebars, t.context.def) - .instance() - .render() - ); - t.is(error.message, Msg.messages.oneRoot(t.context.def)); -}); - -test("ensures that data is a function", t => { - t.context.def.data = {}; - const error = t.throws(() => Component.register(t.context.id, Handlebars, t.context.def).instance()); - t.is(error.message, Msg.messages.dataFn(t.context.def)); -}); - -test.serial("warns if you are pass undefined as a prop", t => { - sinon.stub(Msg, "warn"); - Component.register(t.context.id, Handlebars, t.context.def).instance({ bad: undefined }); - const args = Msg.warn.lastCall.args; - t.is(args[0], "propUndef"); - t.deepEqual(args[1], { name: "test", key: "bad" }); -}); diff --git a/test/_old/component.spec.js b/test/_old/component.spec.js deleted file mode 100644 index 68ee9d1..0000000 --- a/test/_old/component.spec.js +++ /dev/null @@ -1,154 +0,0 @@ -import test from "ava"; -import sinon from "sinon"; -import ReBars from "../src/index.js"; -import Handlebars from "handlebars"; -import Component from "../src/component.js"; -import ProxyTrap from "../src/proxy-trap.js"; -import Utils from "../src/utils/index.js"; -import Core from "../src/helpers/core.js"; -import Events from "../src/helpers/events.js"; -import Watch from "../src/helpers/watch.js"; - -test.beforeEach(t => { - window.Handlebars = Handlebars; - t.context.$el = document.createElement("div"); - document.body.append(t.context.$el); - - const { id } = ReBars.app({ - $el: t.context.$el, - root: { name: "root", template: "

" }, - }); - - t.context.def = { - template: "

{{ name }}

", - name: "test", - data: () => ({ name: "David" }), - }; - - t.context.id = id; -}); - -test.afterEach.always(t => { - t.context.$el.remove(); - sinon.restore(); -}); - -test("will render the component as root", t => { - const output = Component.register(t.context.id, Handlebars, t.context.def) - .instance() - .render(); - - t.is(output.includes(">David"), true); - t.is(output.includes("data-rbs-comp="), true); -}); - -test("keeps $props separated", t => { - t.context.def.template = "
{{ name }} {{ $props.hobby }}
"; - const output = Component.register(t.context.id, Handlebars, t.context.def) - .instance({ hobby: "bonsai" }) - .render(); - - t.is(output.includes("David"), true); - t.is(output.includes("bonsai"), true); -}); - -test("methods are scoped to the scope", t => { - t.context.def.methods = { - sup() { - t.is("$methods" in this, true); - t.is("$props" in this, true); - t.is("$refs" in this, true); - }, - }; - - const { scope } = Component.register(t.context.id, Handlebars, t.context.def).instance(); - scope.$methods.sup(); -}); - -test("data functions are scoped", t => { - t.context.def.data = function() { - return { - name: "fred", - computed() { - t.is(this.name, "fred"); - return this.name; - }, - }; - }; - - const { scope } = Component.register(t.context.id, Handlebars, t.context.def).instance(); - t.is(scope.computed(), "fred"); -}); - -test("scope returns keys", t => { - const { scope } = Component.register(t.context.id, Handlebars, t.context.def).instance(); - t.is(typeof scope.$refs, "function"); - t.is(typeof scope.$props, "object"); - t.is(typeof scope.$methods, "object"); - t.is(typeof scope.$watchers, "object"); - t.is(typeof scope.$hooks, "object"); - t.is(typeof scope.$name, "string"); -}); - -test("hook created gets called with scope of the instance", t => { - t.context.def.data = () => ({ name: "dave" }); - t.context.def.hooks = { - created() { - t.is(this.name, "dave"); - }, - }; - - Component.register(t.context.id, Handlebars, t.context.def).instance(); -}); - -test.serial("registers core helpers for instance", t => { - sinon.stub(Core, "register"); - - Component.register(t.context.id, Handlebars, t.context.def).instance(); - const { appId, instance, helpers, name } = Core.register.lastCall.args[0]; - - t.is(typeof helpers, "object"); - t.is(typeof appId, "string"); - t.is(typeof instance, "object"); - t.is(name, "test"); -}); - -test.serial("registers event helpers for instance", t => { - sinon.stub(Events, "register"); - Component.register(t.context.id, Handlebars, t.context.def).instance(); - t.is(typeof Events.register.lastCall.args[0], "object"); -}); - -test.serial("registers watch helpers for instance", t => { - sinon.stub(Watch, "register"); - Component.register(t.context.id, Handlebars, t.context.def).instance(); - t.is(typeof Watch.register.lastCall.args[0], "object"); -}); - -test.serial("creates a proxy trap", t => { - const watchStub = sinon.stub(); - sinon.stub(ProxyTrap, "create").returns({ data: { name: "fred", $props: { thing: true } }, watch: watchStub }); - const { scope } = Component.register(t.context.id, Handlebars, t.context.def).instance({ - hello: "prop", - }); - const args = ProxyTrap.create.lastCall.args[0]; - - t.is(args.$props.hello, "prop"); - t.is(args.$name, "test"); - t.is(scope.$props.thing, true); - t.is(scope.name, "fred"); - t.is(watchStub.called, false); -}); - -test.serial("does not begin watching until after render", t => { - const watchStub = sinon.stub(); - - sinon.stub(ProxyTrap, "create").returns({ data: {}, watch: watchStub }); - sinon.stub(Utils.dom, "tagComponent").returns("theWrapper"); - - const { render } = Component.register(t.context.id, Handlebars, t.context.def).instance(); - - t.is(watchStub.called, false); - t.is(render(), "theWrapper"); - t.is(watchStub.called, true); -}); diff --git a/test/_old/global-handlers.spec.js b/test/_old/global-handlers.spec.js deleted file mode 100644 index b67bcfd..0000000 --- a/test/_old/global-handlers.spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import test from "ava"; -import ReBars from "../src/index.js"; -import Handlebars from "handlebars"; -import Msg from "../src/Msg.js"; -import Utils from "../src/utils/index.js"; -import Component from "../src/component.js"; -import sinon from "sinon"; - -test.beforeEach(t => { - window.Handlebars = Handlebars; - t.context.$el = document.createElement("div"); - document.body.append(t.context.$el); - - sinon.stub(Component, "register").returns({ - instance() { - return { render() {} }; - }, - }); - ReBars.app({ - $el: t.context.$el, - root: {}, - }); - t.context.scope = { $name: "test", $methods: {} }; - sinon.stub(Utils, "getStorage").returns({ scope: t.context.scope }); -}); - -test.afterEach.always(t => { - t.context.$el.remove(); - sinon.restore(); -}); - -test.serial("trigger: calls the storage to get the scope", t => { - const methodStub = sinon.stub(); - t.context.scope.$methods = { myMethod: methodStub }; - window.rbs.handlers.trigger("appId", "cId", "myMethod", "optionalParam"); - const storageArgs = Utils.getStorage.lastCall.args; - - t.is(storageArgs[0], "appId"); - t.is(methodStub.called, true); - t.is(methodStub.lastCall.args[0], "optionalParam"); - t.is(storageArgs[1], "cId"); -}); - -test.serial("trigger: throws if the method is not found", t => { - t.context.scope.$methods = {}; - const error = t.throws(() => window.rbs.handlers.trigger("appId", "cId", "missing")); - t.is(error.message, Msg.messages.noMethod({ name: "test", methodName: "missing" })); -}); - -test.serial("bound: will update the path if found", t => { - t.context.scope.name = { first: "david" }; - const event = { target: { value: "Fred" } }; - - window.rbs.handlers.bound("appId", "cId", event, "name.first"); - t.is(t.context.scope.name.first, "Fred"); -}); - -test.serial("bound: throws error if path is not found", t => { - t.context.scope.name = {}; - const event = { target: { value: "Fred" } }; - const error = t.throws(() => window.rbs.handlers.bound("appId", "cId", event, "name.first")); - t.is(error.message, Msg.messages.badPath({ path: "name.first" })); -}); diff --git a/test/fixtures/helpers.hbs b/test/fixtures/helpers.hbs new file mode 100644 index 0000000..d2a0252 --- /dev/null +++ b/test/fixtures/helpers.hbs @@ -0,0 +1,47 @@ + + +

Dynamic

+

Static

+ + +

Dynamic

+

Static

+ + +{{#watch}} + + +{{/watch}} + + + + + + + + + + + + + + + + +{{#watch "name" }} +
{{ name.first }} {{ name.last }}
+{{/watch}} + +{{#watch tag="ul"}} + {{#each friends as | friend | }} +
  • + {{ friend.name }} - {{ friend.hobby }} +
  • + {{/each}} +{{/watch}} diff --git a/test/fixtures/helpers.js b/test/fixtures/helpers.js new file mode 100644 index 0000000..76946f8 --- /dev/null +++ b/test/fixtures/helpers.js @@ -0,0 +1,45 @@ +export default { + data() { + return { + name: { + first: "Dave", + last: "Morrow", + }, + friends: [ + { id: 1, hobby: "photography", name: "Frank" }, + { id: 2, hobby: "biking", name: "Eric" }, + { id: 3, hobby: "building", name: "Matt" }, + { id: 4, hobby: "camping", name: "Tod" }, + { id: 5, hobby: "hiking", name: "Keith" }, + ], + show: false, + previousName: {}, + }; + }, + + trace: false, + + methods: { + changeName({ methods }, first, last) { + methods.storePrev(); + this.name.first = first; + this.name.last = last; + }, + + storePrev() { + this.previousName.first = this.name.first; + this.previousName.last = this.name.last; + }, + + restoreName() { + this.name.first = this.previousName.first; + this.name.last = this.previousName.last; + }, + }, + + hooks: { + beforeRender({ methods }) { + methods.storePrev(); + }, + }, +}; diff --git a/test/helpers.js b/test/helpers.js index 9c7d2a2..722359e 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,6 +1,10 @@ import ReBars from "../src/index.js"; import Handlebars from "handlebars"; import Sinon from "sinon"; +import fs from "fs"; +import path from "path"; + +const fixtureDir = path.join(__dirname, "fixtures"); const _query = ($container, selector) => { const $matches = $container.querySelectorAll(selector); @@ -25,9 +29,11 @@ export default { return _query(t.context.$el, selector); }, - trigger(t, val, eventType = "click", search = "ref") { + async trigger(t, val, eventType = "click", search = "ref") { const $el = search === "query" ? this.find(t, val) : this.ref(t, val); $el.dispatchEvent(new MouseEvent(eventType, { bubbles: true })); + await t.context.scope.$nextTick(); + return $el; }, cleanup(t) { @@ -35,24 +41,21 @@ export default { Sinon.restore(); }, - buildContext(t, app) { + buildFixture(t, name) { + const app = require(`${fixtureDir}/${name}.js`).default; + app.template = fs.readFileSync(`${fixtureDir}/${name}.hbs`, "utf-8"); + return this.buildContext(t, app); + }, + + async buildContext(t, app) { + window.Handlebars = Handlebars; if (t.context.$el) t.context.$el.remove(); const $el = document.createElement("div"); document.body.append($el); t.context.$el = $el; - t.context.app = ReBars.app({ ...app, $el, Handlebars, trace: false }); - - const [id, inst] = Object.entries(t.context.app.components.instances)[0]; - t.context.id = id; - t.context.inst = inst; - t.context.scope = inst.scope; - t.context.$refs = inst.scope.$refs(); - - return this.wait(); - }, - - getCompByName(t, name) { - return Object.values(t.context.app.components.instances).find(inst => inst.scope.$name === name); + t.context.app = ReBars.app({ Handlebars, trace: false, ...app }); + t.context.scope = await t.context.app.render($el); + await t.context.scope.$nextTick(); }, }; diff --git a/test/setup.js b/test/setup.js index 0c104ec..5c8dcea 100644 --- a/test/setup.js +++ b/test/setup.js @@ -1 +1,3 @@ require("browser-env")(); + +const org = console.log; diff --git a/test/specs/app.spec.js b/test/specs/app.spec.js new file mode 100644 index 0000000..4bcb08f --- /dev/null +++ b/test/specs/app.spec.js @@ -0,0 +1,105 @@ +import test from "ava"; +import ReBars from "../../src/index.js"; +import Handlebars from "handlebars"; +import Sinon from "sinon"; +import Helpers from "../helpers.js"; +import ProxyTrap from "../../src/proxy-trap.js"; + +test.beforeEach(async t => { + window.Handlebars = Handlebars; + + await Helpers.buildContext(t, { + template: "

    Hello there...

    ", + data: { name: "David" }, + methods: { foo: Sinon.stub() }, + }); +}); + +test.afterEach.always(Helpers.cleanup); + +test("ReBars exports properly", t => { + t.is(typeof ReBars.app, "function"); + t.is(typeof ReBars.load, "function"); + t.is(typeof window.ReBars, "object"); +}); + +test("returns object from app", t => { + t.is(typeof t.context.app.render, "function"); + t.is(typeof t.context.app.store, "object"); + t.is(typeof t.context.app.store.renders, "object"); + t.is(typeof t.context.app.store.handlers, "object"); + t.is(typeof t.context.app.instance, "object"); +}); + +test("renders to the element", t => { + t.is(t.context.scope.$app.innerHTML, "

    Hello there...

    "); +}); + +test("builds the scope", t => { + const { $app, rootData, methods, $refs, $nextTick } = t.context.scope; + + t.is(typeof $nextTick, "function"); + t.is(typeof $refs, "function"); + t.is(typeof methods, "object"); + t.is(typeof rootData, "object"); + + t.is($app.nodeType, Node.ELEMENT_NODE); + t.is(rootData.name, "David"); + t.is(typeof methods.foo, "function"); +}); + +// serial tests +test.serial("functions are bound", async t => { + function foo(context) { + t.is(this.name, "David"); + t.is(typeof context.methods, "object"); + } + + await Helpers.buildContext(t, { + template: "

    Hello there...

    ", + data: { name: "David" }, + methods: { foo }, + }); + + t.context.scope.methods.foo(); +}); + +test.serial("throws if cant find Handlebars", t => { + delete window.Handlebars; + + const err = t.throws(() => { + ReBars.app({ trace: false, template: "" }); + }); + + t.is(err.message.includes("needs Handlebars"), true); +}); + +test.serial("creates proxy out of data", async t => { + Sinon.stub(ProxyTrap, "create"); + + await Helpers.buildContext(t, { + template: "

    hi

    ", + data: { name: "David" }, + }); + + t.is(ProxyTrap.create.called, true); + t.deepEqual(Object.keys(ProxyTrap.create.lastCall.args[0]).sort(), ["$app", "data", "methods"]); +}); + +test.serial("throws if cant find target", async t => { + const err = await t.throwsAsync(() => { + return ReBars.app({ trace: false, template: "" }).render("nope"); + }); + + t.is(err.message.includes("nope"), true); + t.is(err.message.includes("could not be found"), true); +}); + +test.serial("can take a Handlebars param", async t => { + delete window.handlebars; + const Handlebars = { create: Sinon.stub().returns({ foo: true }) }; + const app = ReBars.app({ trace: false, template: "", Handlebars }); + + t.is(Handlebars.create.called, true); + t.is(app.instance.foo, true); +}); diff --git a/test/specs/helpers/bind-helper.spec.js b/test/specs/helpers/bind-helper.spec.js new file mode 100644 index 0000000..dffee95 --- /dev/null +++ b/test/specs/helpers/bind-helper.spec.js @@ -0,0 +1,31 @@ +import test from "ava"; +import Helpers from "../../helpers.js"; + +test.beforeEach(async t => { + await Helpers.buildFixture(t, "helpers"); +}); + +test.afterEach.always(Helpers.cleanup); + +test("bind the event to the prop", async t => { + await Helpers.trigger(t, "bindBtn1"); + t.is(Helpers.ref(t, "nameTarget").innerHTML, "Rick Morrow"); +}); + +test("can force the value", async t => { + await Helpers.trigger(t, "bindBtn2"); + t.is(Helpers.ref(t, "nameTarget").innerHTML, "Dave Clark"); +}); + +test("sets null if no value", async t => { + await Helpers.trigger(t, "bindBtn3"); + t.is(t.context.scope.rootData.name.last, null); +}); + +test("sets the value from an input", async t => { + const $input = t.context.scope.$refs().bindInput; + $input.value = "Eric"; + + await Helpers.trigger(t, "bindInput", "input"); + t.is(t.context.scope.rootData.name.first, "Eric"); +}); diff --git a/test/specs/helpers/bound.spec.js b/test/specs/helpers/bound.spec.js deleted file mode 100644 index ca1bcef..0000000 --- a/test/specs/helpers/bound.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; - -test.afterEach.always(Helpers.cleanup); - -test("binds the input", async t => { - await Helpers.buildContext(t, { - root: { - name: "test", - template: "
    ", - data: () => ({ name: "dave" }), - }, - }); - - const $input = Helpers.find(t, "input"); - t.is($input.value, "dave"); - t.is($input.getAttribute("ref"), "name"); -}); - -test.serial("throws if pass object", async t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    ", - data: () => ({ name: { first: "dave" } }), - }, - }); - }); - - t.true(message.includes("bound")); - t.true(message.includes("test:")); - t.true(message.includes("{{ bound name }}")); -}); - -test.serial("throws if path is not found", async t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    ", - }, - }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("{{ bound 'no.exist' }}")); -}); - -test("updates the bound value on change", async t => { - await Helpers.buildContext(t, { - root: { - name: "test", - template: "
    ", - data: () => ({ name: "david" }), - }, - }); - - Helpers.ref(t, "name").value = "Mike"; - Helpers.trigger(t, "name", "input"); - await Helpers.wait(); - t.is(t.context.scope.name, "Mike"); -}); - -test("can take ref as an arg", async t => { - await Helpers.buildContext(t, { - root: { - name: "test", - template: "
    ", - data: () => ({ name: "david" }), - }, - }); - - t.is(Helpers.ref(t, "customRef").value, "david"); -}); diff --git a/test/specs/helpers/component.spec.js b/test/specs/helpers/component.spec.js deleted file mode 100644 index f14c1b9..0000000 --- a/test/specs/helpers/component.spec.js +++ /dev/null @@ -1,148 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; - -test.afterEach.always(Helpers.cleanup); - -test("throws if not registered", t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - root: { - template: "
    {{ component 'nope' }}
    ", - name: "test", - }, - }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("{{ component 'nope' }}")); -}); - -test("ensures there is only one root element", t => { - const root = { - template: "
    ", - name: "test", - }; - - const { message } = t.throws(() => { - Helpers.buildContext(t, { root }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("multiple root")); - t.true(message.includes(root.template)); -}); - -test("cannot have

    as root", t => { - const root = { - template: "

    ", - name: "test", - }; - - const { message } = t.throws(() => { - Helpers.buildContext(t, { root }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("

    cannot be")); - t.true(message.includes(root.template)); -}); - -test("cannot have watch as root", t => { - const root = { - template: "{{#watch name }}{{/watch}}", - name: "test", - data: () => ({ name: "d" }), - }; - - const { message } = t.throws(() => { - Helpers.buildContext(t, { root }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("watch")); - t.true(message.includes(root.template)); -}); - -test("can render global components", async t => { - await Helpers.buildContext(t, { - root: { - template: "

    {{ component 'child' }}
    ", - name: "test", - }, - components: [{ name: "child", template: "
    Hello Child!
    " }], - }); - - t.is(t.context.$el.innerHTML.includes("Hello Child!"), true); -}); - -test("can render local components", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ component 'child' }}
    ", - name: "test", - components: [{ name: "child", template: "
    Hello Child!
    " }], - }, - }); - - t.is(t.context.$el.innerHTML.includes("Hello Child!"), true); -}); - -test("passes props to the child", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ component 'child' name='David' hobby='Bonsai' }}
    ", - name: "test", - components: [{ name: "child", template: "
    " }], - }, - }); - const { scope } = Helpers.getCompByName(t, "child"); - t.is(scope.$props.name, "David"); - t.is(scope.$props.hobby, "Bonsai"); -}); - -test("can pass data as props", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ component 'child' name=name }}
    ", - name: "test", - data: () => ({ name: "David" }), - components: [{ name: "child", template: "
    " }], - }, - }); - const { scope } = Helpers.getCompByName(t, "child"); - t.is(scope.$props.name, "David"); -}); - -test("can pass objects as props", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ component 'child' name=name }}
    ", - name: "test", - data: () => ({ name: { first: "David" } }), - components: [{ name: "child", template: "
    " }], - }, - }); - const { scope } = Helpers.getCompByName(t, "child"); - t.is(scope.$props.name.first, "David"); -}); - -test("can pass methods as props", async t => { - let methodScope; - await Helpers.buildContext(t, { - root: { - template: "
    {{ component 'child' changeName=$methods.changeName }}
    ", - name: "test", - data: () => ({ name: "David" }), - methods: { - changeName() { - methodScope = this; - }, - }, - components: [{ name: "child", template: "
    " }], - }, - }); - const { scope } = Helpers.getCompByName(t, "child"); - scope.$props.changeName(); - t.is(typeof scope.$props.changeName, "function"); - t.is(methodScope.name, "David"); -}); diff --git a/test/specs/helpers/debug.spec.js b/test/specs/helpers/debug.spec.js deleted file mode 100644 index 86c2777..0000000 --- a/test/specs/helpers/debug.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; -import Utils from "../../../src/utils/index.js"; - -const Comp = { - template: /*html*/ ` -
    - {{ debug . ref="fullDebug" }} - {{ debug name ref="nameDebug" }} - {{ debug name.first ref="nameFirst" class="foobar" }} -
    - `, - name: "test", - data() { - return { name: { first: "david" } }; - }, -}; - -test.beforeEach(t => { - Helpers.buildContext(t, { root: Comp }); -}); - -test.afterEach.always(Helpers.cleanup); - -test("debugs all", t => { - const content = Helpers.ref(t, "fullDebug").innerHTML; - t.is(content, Utils.stringify(t.context.scope)); -}); - -test("debugs 'name'", t => { - const content = Helpers.ref(t, "nameDebug").innerHTML; - t.is(content, Utils.stringify(t.context.scope.name)); -}); - -test("debugs 'name.first'", t => { - t.is(t.context.$refs.nameFirst.getAttribute("class"), "foobar"); - t.is(t.context.$refs.nameFirst.innerHTML, Utils.stringify(t.context.scope.name.first)); -}); - -test.serial("throws if path not found", t => { - const root = { template: "{{ debug doesNotExist }}", name: "Bad" }; - const error = t.throws(() => Helpers.buildContext(t, { root })); - - t.true(error.message.includes("Bad:")); - t.true(error.message.includes("{{ debug doesNotExist }}")); -}); - -test.serial("throws if path not found on nested obj", t => { - const root = { template: "{{ debug name.last }}", name: "Bad" }; - const error = t.throws(() => Helpers.buildContext(t, { root })); - t.true(error.message.includes("Bad:")); - t.true(error.message.includes("{{ debug name.last }}")); -}); diff --git a/test/specs/helpers/is-component.spec.js b/test/specs/helpers/is-component.spec.js deleted file mode 100644 index f017a73..0000000 --- a/test/specs/helpers/is-component.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; - -test.afterEach.always(Helpers.cleanup); - -test("false if not registered", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ isComponent 'nope' }}
    ", - name: "test", - }, - }); - - t.is(t.context.scope.$el().innerHTML, "false"); -}); - -test("true if registered", async t => { - await Helpers.buildContext(t, { - root: { - template: "
    {{ isComponent 'child' }}
    ", - components: [{ name: "child", template: "
    " }], - name: "test", - }, - }); - - t.is(t.context.scope.$el().innerHTML, "true"); -}); - -test("works on global components", async t => { - await Helpers.buildContext(t, { - components: [{ name: "child", template: "
    " }], - root: { - template: "
    {{ isComponent 'child' }}
    ", - name: "test", - }, - }); - - t.is(t.context.scope.$el().innerHTML, "true"); -}); diff --git a/test/specs/helpers/key-helper.spec.js b/test/specs/helpers/key-helper.spec.js new file mode 100644 index 0000000..b4cdd76 --- /dev/null +++ b/test/specs/helpers/key-helper.spec.js @@ -0,0 +1,33 @@ +import test from "ava"; +import Utils from "../../../src/utils/index.js"; +import Helpers from "../../helpers.js"; +import Config from "../../../src/config.js"; + +const key = Config.attrs.key; + +test.beforeEach(async t => { + await Helpers.buildFixture(t, "helpers"); +}); + +test.afterEach.always(Helpers.cleanup); + +test("adds key to the span", t => { + const { keyH1, keyH2 } = t.context.scope.$refs(); + t.is(keyH1.getAttribute(key), "Dave"); + t.is(keyH2.getAttribute(key), "Static"); +}); + +test("can find keys on the DOM", t => { + t.is(Utils.dom.findAttr(key, "Dave").innerHTML, "Dynamic"); + t.is(Utils.dom.findAttr(key, "Static").innerHTML, "Static"); +}); + +test("using keys, updates only patch", async t => { + const { $refs, rootData, $nextTick } = t.context.scope; + const { friendFrank, friendEric } = $refs(); + + rootData.friends[1].hobby = "running"; + await $nextTick(); + t.is($refs().friendFrank.isEqualNode(friendFrank), true); + t.is($refs().friendEric.isEqualNode(friendEric), false); +}); diff --git a/test/specs/helpers/method.spec.js b/test/specs/helpers/method.spec.js deleted file mode 100644 index 4bd16a7..0000000 --- a/test/specs/helpers/method.spec.js +++ /dev/null @@ -1,91 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; - -test.afterEach.always(Helpers.cleanup); - -test("captures the event", async t => { - let args; - let methodScope; - - await Helpers.buildContext(t, { - root: { - name: "test", - template: "", - methods: { - clickHandler() { - args = arguments; - methodScope = this; - }, - }, - }, - }); - - Helpers.trigger(t, "clicker", "click"); - const event = args[0]; - - t.is(event instanceof MouseEvent, true); - t.is(event.target, Helpers.ref(t, "clicker")); - t.is(event.type, "click"); - t.is(methodScope.$name, "test"); - t.is(typeof methodScope.$methods, "object"); -}); - -test("takes an argument for event type", async t => { - let args; - await Helpers.buildContext(t, { - root: { - name: "test", - template: "", - methods: { - handler() { - args = arguments; - }, - }, - }, - }); - - Helpers.trigger(t, "clicker", "keyup"); - const [event, msg] = args; - - t.is(event instanceof MouseEvent, true); - t.is(msg, "kechow!"); - t.is(event.type, "keyup"); -}); - -test("throws if method not defined", async t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "", - }, - }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("{{ method 'noper' }}")); -}); - -test("takes data as args", async t => { - let args; - await Helpers.buildContext(t, { - root: { - name: "test", - template: "", - data() { - return { name: { first: "David" } }; - }, - methods: { - handler() { - args = arguments; - }, - }, - }, - }); - - Helpers.trigger(t, "clicker"); - const [event, name] = args; - - t.is(event instanceof MouseEvent, true); - t.is(name, "David"); -}); diff --git a/test/specs/helpers/on-helper.spec.js b/test/specs/helpers/on-helper.spec.js new file mode 100644 index 0000000..a7a86ef --- /dev/null +++ b/test/specs/helpers/on-helper.spec.js @@ -0,0 +1,20 @@ +import test from "ava"; +import Helpers from "../../helpers.js"; + +test.beforeEach(async t => { + await Helpers.buildFixture(t, "helpers"); +}); + +test.afterEach.always(Helpers.cleanup); + +test("on triggers the methods", async t => { + await Helpers.trigger(t, "onBtn1"); + t.is(Helpers.ref(t, "nameTarget").innerHTML, "Rick James"); +}); + +test("on can trigger multiple events", async t => { + await Helpers.trigger(t, "onBtn2", "mouseover"); + t.is(Helpers.ref(t, "nameTarget").innerHTML, "Gary Clark"); + await Helpers.trigger(t, "onBtn2", "mouseout"); + t.is(Helpers.ref(t, "nameTarget").innerHTML, "Dave Morrow"); +}); diff --git a/test/specs/helpers/only-if-helper.spec.js b/test/specs/helpers/only-if-helper.spec.js new file mode 100644 index 0000000..7aae1c5 --- /dev/null +++ b/test/specs/helpers/only-if-helper.spec.js @@ -0,0 +1,23 @@ +import test from "ava"; +import Helpers from "../../helpers.js"; + +test.beforeEach(async t => { + await Helpers.buildFixture(t, "helpers"); +}); + +test.afterEach.always(Helpers.cleanup); + +test("switches conditional rendering", async t => { + const { $refs, rootData, $nextTick } = t.context.scope; + + t.is($refs().onlyIfName.disabled, true); + t.is($refs().onlyIfShow.disabled, false); + + rootData.show = true; + await $nextTick(); + t.is($refs().onlyIfShow.disabled, true); + + rootData.name.first = null; + await $nextTick(); + t.is($refs().onlyIfName.disabled, false); +}); diff --git a/test/specs/helpers/ref-helper.spec.js b/test/specs/helpers/ref-helper.spec.js new file mode 100644 index 0000000..a6903ba --- /dev/null +++ b/test/specs/helpers/ref-helper.spec.js @@ -0,0 +1,20 @@ +import test from "ava"; +import Helpers from "../../helpers.js"; + +test.beforeEach(async t => { + await Helpers.buildFixture(t, "helpers"); +}); + +test.afterEach.always(Helpers.cleanup); + +test("$refs method returns all refs", t => { + const $refs = t.context.scope.$refs(); + + t.is(typeof $refs, "object"); + + t.is("Dave" in $refs, true); + t.is("static" in $refs, true); + + t.is($refs.Dave.innerHTML, "Dynamic"); + t.is($refs.static.innerHTML, "Static"); +}); diff --git a/test/specs/helpers/watch.spec.js b/test/specs/helpers/watch.spec.js deleted file mode 100644 index 4796ab6..0000000 --- a/test/specs/helpers/watch.spec.js +++ /dev/null @@ -1,163 +0,0 @@ -import test from "ava"; -import Helpers from "../../helpers.js"; - -test.afterEach.always(t => { - Helpers.cleanup(t); -}); - -test("throws if value undefined", t => { - const root = { - name: "test", - template: "
    {{#watch name }}{{/watch}}
    ", - }; - - const { message } = t.throws(() => { - Helpers.buildContext(t, { root }); - }); - - t.true(message.includes("test:")); - t.true(message.includes(root.template)); -}); - -test.only("throws any arg undefined", t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - root: { - name: "test", - data: () => ({ name: "dave" }), - template: "
    {{#watch 'name' fred }}{{/watch}}
    ", - }, - }); - }); - - t.true(message.includes("test:")); - t.true(message.includes("{{#watch 'name'")); -}); - -test("does not throw if passed a string", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'some.*.crazy.*.path' }}{{/watch}}
    ", - }, - }); - - const { path } = Object.values(t.context.inst.renders)[0]; - t.deepEqual(path, ["some.*.crazy.*.path"]); -}); - -test("builds the dom $el", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'name' ref='watcher' }}{{/watch}}
    ", - data: () => ({ name: "Dave" }), - }, - }); - - const $watch = Helpers.ref(t, "watcher"); - - t.is($watch.nodeName, "SPAN"); - t.is($watch.getAttribute("style"), "display:none;"); - t.true($watch.dataset.rbsWatch.startsWith("rbs")); -}); - -test("takes a tag, and or optional attrs ", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'name' tag='div'ref='watcher' foo='bar' }}{{/watch}}
    ", - data: () => ({ name: "Dave" }), - }, - }); - - const $watch = Helpers.ref(t, "watcher"); - - t.is($watch.nodeName, "DIV"); - t.is($watch.getAttribute("foo"), "bar"); -}); - -test("can watch multiple items", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'name' 'hobby' }}{{/watch}}
    ", - data: () => ({ name: "Dave", hobby: "bonsai" }), - }, - }); - - const { path } = Object.values(t.context.inst.renders)[0]; - t.deepEqual(path, ["name", "hobby"]); -}); - -test("adds the id to renders", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'name' 'hobby' ref='watch' }}{{/watch}}
    ", - data: () => ({ name: "Dave", hobby: "bonsai" }), - }, - }); - const id = t.context.$refs.watch.dataset.rbsWatch; - const { path, render } = Object.values(t.context.inst.renders)[id]; - t.is(typeof render, "function"); - t.deepEqual(path, ["name", "hobby"]); -}); - -test("uses wildcard if an Object", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch name }}{{/watch}}
    ", - data: () => ({ name: { first: "Dave", last: "Morrow" } }), - }, - }); - - const { path } = Object.values(t.context.inst.renders)[0]; - t.deepEqual(path, ["name.*"]); -}); - -test("uses wildcard on Index of Array", t => { - Helpers.buildContext(t, { - root: { - name: "test", - template: "
    {{#watch 'friends.*.name' }}{{/watch}}
    ", - data: () => ({ friends: ["Mike", "Jason"] }), - }, - }); - - const { path } = Object.values(t.context.inst.renders)[0]; - t.deepEqual(path, ["friends.*.name"]); -}); - -test("throws if watch $prop", t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - trace: true, - root: { - name: "test", - template: "
    {{ component 'child' name='dave' }}
    ", - components: [{ name: "child", template: "
    {{#watch $props }}{{/watch}}
    " }], - }, - }); - }); - - t.true(message.toLowerCase().includes("do not watch $props")); - t.true(message.includes("{{#watch $props }}")); -}); - -test("throws if watch $props even if arg is String", t => { - const { message } = t.throws(() => { - Helpers.buildContext(t, { - trace: true, - root: { - name: "test", - template: "
    {{ component 'child' name='dave' }}
    ", - components: [{ name: "child", template: "
    {{#watch '$props.name' }}{{/watch}}
    " }], - }, - }); - }); - - t.true(message.toLowerCase().includes("do not watch $props")); - t.true(message.includes("{{#watch '$props.name' }}")); -}); diff --git a/test/specs/rendering.spec.js b/test/specs/rendering.spec.js deleted file mode 100644 index 04726ae..0000000 --- a/test/specs/rendering.spec.js +++ /dev/null @@ -1,70 +0,0 @@ -import test from "ava"; -import Helpers from "../helpers.js"; - -const DemoComponent = { - template: /*html*/ ` -
    - {{#watch name }} -

    {{ name.first }}

    - {{/watch}} -

    {{ fullName }}

    - -
    - `, - name: "test", - data() { - return { - fullName() { - return `${this.name.first}, ${this.name.last}`; - }, - name: { first: "Luther", last: "Allison" }, - }; - }, - methods: { - changeName(event, first, last) { - this.name.first = first; - this.name.last = last; - }, - }, -}; - -test.beforeEach(t => { - Helpers.buildContext(t, { root: DemoComponent }); -}); - -test.afterEach.always(t => { - t.context.$el.remove(); -}); - -test("renders data values", t => { - t.is(Helpers.ref(t, "title").innerHTML, "Luther"); -}); - -test("adds methods to scope", t => { - t.is(typeof t.context.scope.$el, "function"); - t.is(typeof t.context.scope.$refs, "function"); - t.is(typeof t.context.scope.$methods.changeName, "function"); -}); - -test("adds internals to scope", t => { - t.is(typeof t.context.scope.$_componentId, "string"); - t.is(t.context.scope.$name, "test"); -}); - -test("renders data methods", t => { - t.is(Helpers.ref(t, "fullName").innerHTML, "Luther, Allison"); -}); - -test("re-renders on change", async t => { - t.is(Helpers.ref(t, "title").innerHTML, "Luther"); - t.context.scope.name.first = "fred"; - await Helpers.wait(); - t.is(Helpers.ref(t, "title").innerHTML, "fred"); -}); - -test("event handlers work", async t => { - Helpers.ref(t, "changeBtn").click(); - t.is(t.context.scope.fullName(), "Freddy, King"); - await Helpers.wait(); - t.is(Helpers.ref(t, "title").innerHTML, "Freddy"); -});