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