(function(r,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],c):(r=typeof globalThis<"u"?globalThis:r||self,c(r.trame_dataclass={},r.Vue))})(this,function(r,c){"use strict";function f(l,t,s){if(s.data._id!==l){s.data._id=l;const e=Object.keys(s.data);for(let i of e)delete s.data[i]}Object.assign(s.data,t.refs)}class d{constructor(){this.client=null,this.subscription=null,this.dataStates={},this.dataTypes={},this.typeDefinitions={},this.vueComponents={},this.internalReactiveObjects={},this.dataToVue={},this.pendingClientServerQueue=[],this.pendingFlushRequest=0}connect(t){this.client||!t||(this.client=t,this.subscription=t.getConnection().getSession().subscribe("trame.dataclass.publish",async([s])=>{const{id:e,state:i}=s;Object.assign(this.dataStates[e].server,i);for(const[n,a]of Object.entries(i))this.isDataClass(e,n)?await this.handleNestedDataClass(e,n,a):this.dataStates[e].refs[n].value=a}))}updateServer(t,s,e){this.pendingClientServerQueue.push([t,s,e]),this.flushToServer()}async flushToServer(){if(this.pendingFlushRequest)return;this.pendingFlushRequest++;const t={};let s=0;for(;this.pendingClientServerQueue.length;){const[e,i,n]=this.pendingClientServerQueue.shift();let a=n;if(n!==null&&this.isDataClass(e,i))if(Array.isArray(n))a=n.map(o=>o._id);else if(n._id)a=n._id;else{a={};for(const[o,S]in Object.entries(n))a[o]=S._id}JSON.stringify(this.dataStates[e].server[i])!==JSON.stringify(a)&&(t[e]||(t[e]={}),t[e][i]=a,s++)}if(s)try{await this.client.getConnection().getSession().call("trame.dataclass.state.update",[t])}catch(e){console.error("Network error when pushing client state",e)}this.pendingFlushRequest--,this.pendingClientServerQueue.length&&this.flushToServer()}isDataClass(t,s){return this.typeDefinitions[this.dataTypes[t]].dataclass_containers.includes(s)}async handleNestedDataClass(t,s,e){if(e===null)this.dataStates[t].refs[s].value=null;else if(Array.isArray(e)){const i=[];for(let n=0;n<e.length;n++){const a=e[n];let o=!1;this.internalReactiveObjects[a]||(this.internalReactiveObjects[a]=c.reactive({}),o=!0),i.push(this.internalReactiveObjects[a]),this.dataStates[a]||(o=!1,await this.fetchState(a)),o&&Object.assign(this.internalReactiveObjects[a],this.dataStates[a].refs)}this.dataStates[t].refs[s].value=i}else if(typeof e=="string"){const i=e;this.internalReactiveObjects[i]||(this.internalReactiveObjects[i]=c.reactive({})),this.dataStates[i]?Object.assign(this.internalReactiveObjects[i],this.dataStates[i].refs):await this.fetchState(i)}else{const i=c.reactive({});for(const[n,a]of Object.entries(e))this.internalReactiveObjects[a]||(this.internalReactiveObjects[a]=c.reactive({})),i[n]=this.internalReactiveObjects[a],this.dataStates[a]?Object.assign(this.internalReactiveObjects[a],this.dataStates[a].refs):await this.fetchState(a);this.dataStates[t].refs[s].value=i}}async fetchState(t){const s={_id:t},e=await this.client.getConnection().getSession().call("trame.dataclass.state.get",[t]);this.dataTypes[t]=e.definition,this.dataStates[t]={refs:s,server:e.state},this.typeDefinitions[e.definition]||await this.fetchDefinition(e.definition);for(const[i,n]of Object.entries(e.state))this.isDataClass(t,i)?(s[i]=c.ref(null),await this.handleNestedDataClass(t,i,n)):s[i]=c.ref(n),c.watch(()=>s[i].value,a=>this.updateServer(t,i,a));return this.dataToVue[t]&&this.dataToVue[t].forEach(i=>{f(t,this.dataStates[t],this.vueComponents[i])}),this.internalReactiveObjects[t]&&Object.assign(this.internalReactiveObjects[t],this.dataStates[t].refs),this.dataStates[t]}async fetchDefinition(t){const s=await this.client.getConnection().getSession().call("trame.dataclass.definition.get",[t]);this.typeDefinitions[t]=s}unlink(t,s){this.dataToVue[t]&&(this.dataToVue[t]=this.dataToVue[t].filter(e=>e!==s))}link(t,s){this.dataToVue[t]?this.dataToVue[t].push(s):this.dataToVue[t]=[s],this.dataStates[t]?f(t,this.dataStates[t],this.vueComponents[s]):this.fetchState(t)}connectVueComponent(t,s){var n;const e=(n=this.vueComponents[t])==null?void 0:n.id,i=s.id;this.unlink(e,t),this.vueComponents[t]=s,this.link(i,t)}disconnectVueComponent(t){var e;const s=(e=this.vueComponents[t])==null?void 0:e.id;delete this.vueComponents[t],this.unlink(s,t)}}const h=new d;let p=1;const u={TrameDataclass:{props:["instance"],setup(l){const t=c.inject("trame"),s=c.ref(!1),e=c.reactive({}),i={serverPush:!1},n=`vueDataClass${p++}`;return h.connect(t.client),c.watchEffect(()=>{if(l.instance)s.value=!0,h.connectVueComponent(n,{id:l.instance,data:e,guards:i});else{s.value=!1,h.disconnectVueComponent(n);const a=Object.keys(e);for(;a.length;)delete e[a.pop()]}}),c.onBeforeUnmount(()=>{h.disconnectVueComponent(n)}),{data:e,available:s}},template:'<slot :dataclass="data" :dataclassAvailable="available" ></slot>'}};function v(l){Object.keys(u).forEach(t=>{l.component(t,u[t])})}r.install=v,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
