/* stator v0.1.0 | (c) Chad Smith | github.com/cs01/stator */
const stator=function(){"use strict;";function Reactor(element,html_callback,options={}){let nodes=document.querySelectorAll(element);if(1!==nodes.length)throw`Reactor: querySelector "${element}" matched ${nodes.length} nodes. Expected 1.`;if(-1!==state._elements.indexOf(element))throw`Reactor: querySelector "${element}" is already bound to a Reactor.`;state._elements.push(element),this.element=element,this.node=nodes[0];let default_options={listen_to_global_state:!0,render_on_init:!0,before_render:this.before_render,should_render:this.should_render,before_html_update:this.before_html_update,after_html_update:this.after_html_update,after_render:this.after_render},invalid_options=Object.keys(options).filter(o=>-1===Object.keys(default_options).indexOf(o));if(invalid_options.length>0)return void invalid_options.map(o=>console.error(`Reactor got invalid option "${o}"`));if(this.options=Object.assign(default_options,options),!html_callback||"function"!=typeof html_callback)throw`Reactor did not receive a render callback function. This argument should be a function that returns html to populate the DOM element.`;this._html_callback=html_callback.bind(this),this.options.listen_to_global_state&&state.subscribe(this.render.bind(this)),options.render_on_init&&this.render()}function _clone_obj(obj){if(void 0!==obj)return JSON.parse(JSON.stringify(obj))}function _check_type_match(a,b,key){if(void 0!==a&&void 0!==b&&null!==a&&null!==b){let old_type=typeof a,new_type=typeof b;if(old_type!==new_type)throw console.error("attempted to change ",key," from ",a," (",old_type,") to ",b," (",new_type,")"),"type error"}}function _value_changed(a,b){return(!Array.isArray(a)||!Array.isArray(b)||0!==a.length||0!==b.length)&&a!==b}const state={initialize:function(initial_state){if(state._state_created)throw"cannot create more than one global state";for(let k in initial_state)state._state[k]=_clone_obj(initial_state[k]);state._state_created=!0},options:{debounce_ms:10,max_batched_event_count:10,debug:!1},set:function(key_or_new_state,value){if(1!==arguments.length){let key=key_or_new_state,t=state._state;if(!t.hasOwnProperty(key))throw`cannot create new key after initialization (attempted to create ${key})`;let oldval=t[key];_value_changed(oldval,value)&&(state.options.debug&&console.log("stator "+key,oldval," -> ",value),_check_type_match(oldval,value,key),t[key]=_clone_obj(value),state._debounce_timeout&&(state._clear_debounce_timeout(),state._batched_event_count++),state._batched_event_count>=state.options.max_batched_event_count?(state.options.debug&&console.log(`suppressed ${state._batched_event_count} events (${state.options.max_batched_event_count} max). Emitting event now.`),state.update_subscribers()):state._debounce_timeout=setTimeout(state.update_subscribers,state.options.debounce_ms))}else{let new_state=key_or_new_state;for(let k in new_state)state.set(k,new_state[k])}},get:function(key){if(0===arguments.length)return _clone_obj(state._state);if(state._state.hasOwnProperty(key))return _clone_obj(state._state[key]);throw`attempted to access key that was not set during initialization: ${key}`},subscribe(callback_function){Array.isArray(callback_function)?state._callbacks=state._callbacks.concat(callback_function):state._callbacks.push(callback_function)},unsubscribe(callback_function){state._callbacks=state._callbacks.filter(c=>c!==callback_function)},update_subscribers:function(){state._clear_debounce_timeout(),state._batched_state_changes=0,state._callbacks.map(c=>c())},_callbacks:[],_state:{},_elements:[],_clear_debounce_timeout:function(){clearTimeout(state._debounce_timeout),state._debounce_timeout=null},_debounce_timeout:null,_batched_state_changes:0,_state_created:!1};return Reactor.prototype.should_render=function(r){return!0},Reactor.prototype.before_render=function(r){},Reactor.prototype.after_render=function(r){},Reactor.prototype.before_html_update=function(r){},Reactor.prototype.after_html_update=function(r){},Reactor.prototype.render=function(){if(this.options.before_render(this),this.options.should_render(this)){let node_html=this._html_callback(this);(this.options.force_update||node_html!==this.old_node_html)&&(this.options.force_update=!1,this.before_html_update(this),this.node.innerHTML=node_html,this.after_html_update(this),this.old_node_html=node_html)}this.options.after_render(this)},{state:state,Reactor:Reactor}}(),state=stator.state,Reactor=stator.Reactor;
//# sourceMappingURL=stator.min.js.map