@esengine/network-shared
Version:
ECS Framework网络层 - 共享组件和协议
1 lines • 116 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@esengine/ecs-framework")):"function"==typeof define&&define.amd?define(["exports","@esengine/ecs-framework"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ECSNetworkShared={},e.ECS)}(this,function(e,t){"use strict";var s,i,r,a,n,o,c,l,h,d,u,g,p,m,y;e.MessageType=void 0,(s=e.MessageType||(e.MessageType={})).CONNECT="connect",s.DISCONNECT="disconnect",s.HEARTBEAT="heartbeat",s.SYNC_VAR="sync_var",s.SYNC_BATCH="sync_batch",s.SYNC_SNAPSHOT="sync_snapshot",s.RPC_CALL="rpc_call",s.RPC_RESPONSE="rpc_response",s.ENTITY_CREATE="entity_create",s.ENTITY_DESTROY="entity_destroy",s.ENTITY_UPDATE="entity_update",s.JOIN_ROOM="join_room",s.LEAVE_ROOM="leave_room",s.ROOM_STATE="room_state",s.GAME_EVENT="game_event",s.ERROR="error",s.WARNING="warning",s.INFO="info",e.AuthorityType=void 0,(i=e.AuthorityType||(e.AuthorityType={})).Server="server",i.Client="client",i.Shared="shared",e.NetworkScope=void 0,(r=e.NetworkScope||(e.NetworkScope={})).Global="global",r.Room="room",r.Owner="owner",r.Nearby="nearby",r.Custom="custom",e.SyncMode=void 0,(a=e.SyncMode||(e.SyncMode={})).All="all",a.Owner="owner",a.Others="others",a.Nearby="nearby",a.Custom="custom",e.RpcTarget=void 0,(n=e.RpcTarget||(e.RpcTarget={})).Server="server",n.Client="client",n.All="all",n.Others="others",n.Owner="owner",n.Nearby="nearby",e.RoomState=void 0,(o=e.RoomState||(e.RoomState={})).Waiting="waiting",o.Playing="playing",o.Paused="paused",o.Finished="finished",e.NetworkErrorType=void 0,(c=e.NetworkErrorType||(e.NetworkErrorType={})).CONNECTION_FAILED="connection_failed",c.CONNECTION_LOST="connection_lost",c.AUTHENTICATION_FAILED="authentication_failed",c.PERMISSION_DENIED="permission_denied",c.RATE_LIMITED="rate_limited",c.INVALID_MESSAGE="invalid_message",c.TIMEOUT="timeout",c.UNKNOWN="unknown",e.ConnectionState=void 0,(l=e.ConnectionState||(e.ConnectionState={})).Disconnected="disconnected",l.Connecting="connecting",l.Connected="connected",l.Reconnecting="reconnecting",l.Failed="failed",e.RpcErrorType=void 0,(h=e.RpcErrorType||(e.RpcErrorType={})).METHOD_NOT_FOUND="method_not_found",h.INVALID_ARGUMENTS="invalid_arguments",h.PERMISSION_DENIED="permission_denied",h.TIMEOUT="timeout",h.RATE_LIMITED="rate_limited",h.NETWORK_ERROR="network_error",h.SERVER_ERROR="server_error",h.CLIENT_ERROR="client_error",h.UNKNOWN="unknown",e.RpcCallStatus=void 0,(d=e.RpcCallStatus||(e.RpcCallStatus={})).PENDING="pending",d.SENT="sent",d.PROCESSING="processing",d.COMPLETED="completed",d.FAILED="failed",d.TIMEOUT="timeout",d.CANCELLED="cancelled",e.MessageIdGeneratorType=void 0,(u=e.MessageIdGeneratorType||(e.MessageIdGeneratorType={})).UUID="uuid",u.SNOWFLAKE="snowflake",u.SEQUENTIAL="sequential",u.TIMESTAMP="timestamp";class f{constructor(e=1,t=1){this.sequence=0,this.lastTimestamp=-1,this.workerId=e&(1<<f.WORKER_ID_BITS)-1,this.datacenterId=t&(1<<f.DATACENTER_ID_BITS)-1}generate(){let e=Date.now();if(e<this.lastTimestamp)throw new Error("时钟回拨,无法生成ID");if(e===this.lastTimestamp){if(this.sequence=this.sequence+1&(1<<f.SEQUENCE_BITS)-1,0===this.sequence)for(;e<=this.lastTimestamp;)e=Date.now()}else this.sequence=0;this.lastTimestamp=e;return(e-f.EPOCH<<22|this.datacenterId<<17|this.workerId<<12|this.sequence).toString()}}f.EPOCH=16409952e5,f.WORKER_ID_BITS=5,f.DATACENTER_ID_BITS=5,f.SEQUENCE_BITS=12;e.NetworkEventType=void 0,(g=e.NetworkEventType||(e.NetworkEventType={})).CONNECTION_ESTABLISHED="network:connection:established",g.CONNECTION_LOST="network:connection:lost",g.CONNECTION_ERROR="network:connection:error",g.CONNECTION_TIMEOUT="network:connection:timeout",g.RECONNECTION_STARTED="network:reconnection:started",g.RECONNECTION_SUCCEEDED="network:reconnection:succeeded",g.RECONNECTION_FAILED="network:reconnection:failed",g.IDENTITY_CREATED="network:identity:created",g.IDENTITY_DESTROYED="network:identity:destroyed",g.IDENTITY_OWNER_CHANGED="network:identity:owner:changed",g.IDENTITY_AUTHORITY_CHANGED="network:identity:authority:changed",g.IDENTITY_SYNC_ENABLED="network:identity:sync:enabled",g.IDENTITY_SYNC_DISABLED="network:identity:sync:disabled",g.IDENTITY_PROPERTY_CHANGED="network:identity:property:changed",g.IDENTITY_VISIBLE_CHANGED="network:identity:visible:changed",g.SYNC_STARTED="network:sync:started",g.SYNC_COMPLETED="network:sync:completed",g.SYNC_FAILED="network:sync:failed",g.SYNC_RATE_CHANGED="network:sync:rate:changed",g.SYNC_PRIORITY_CHANGED="network:sync:priority:changed",g.RPC_CALL_SENT="network:rpc:call:sent",g.RPC_CALL_RECEIVED="network:rpc:call:received",g.RPC_RESPONSE_SENT="network:rpc:response:sent",g.RPC_RESPONSE_RECEIVED="network:rpc:response:received",g.RPC_ERROR="network:rpc:error",g.RPC_TIMEOUT="network:rpc:timeout",g.MESSAGE_SENT="network:message:sent",g.MESSAGE_RECEIVED="network:message:received",g.MESSAGE_QUEUED="network:message:queued",g.MESSAGE_DROPPED="network:message:dropped",g.MESSAGE_RETRY="network:message:retry",g.MESSAGE_ACKNOWLEDGED="network:message:acknowledged",g.ROOM_JOINED="network:room:joined",g.ROOM_LEFT="network:room:left",g.ROOM_CREATED="network:room:created",g.ROOM_DESTROYED="network:room:destroyed",g.ROOM_PLAYER_JOINED="network:room:player:joined",g.ROOM_PLAYER_LEFT="network:room:player:left",g.CLIENT_CONNECTED="network:client:connected",g.CLIENT_DISCONNECTED="network:client:disconnected",g.CLIENT_AUTHENTICATED="network:client:authenticated",g.CLIENT_KICKED="network:client:kicked",g.CLIENT_TIMEOUT="network:client:timeout",g.SERVER_STARTED="network:server:started",g.SERVER_STOPPED="network:server:stopped",g.SERVER_ERROR="network:server:error",g.SERVER_OVERLOADED="network:server:overloaded",g.DATA_SYNCHRONIZED="network:data:synchronized",g.DATA_CONFLICT="network:data:conflict",g.DATA_CORRUPTED="network:data:corrupted",g.DATA_VALIDATED="network:data:validated",g.BANDWIDTH_WARNING="network:bandwidth:warning",g.LATENCY_HIGH="network:latency:high",g.PACKET_LOSS_DETECTED="network:packet:loss:detected",g.PERFORMANCE_DEGRADED="network:performance:degraded",e.NetworkEventPriority=void 0,(p=e.NetworkEventPriority||(e.NetworkEventPriority={}))[p.LOW=10]="LOW",p[p.NORMAL=20]="NORMAL",p[p.HIGH=30]="HIGH",p[p.CRITICAL=40]="CRITICAL",p[p.EMERGENCY=50]="EMERGENCY";class T{static createIdentityEventData(e,t,s,i){return{timestamp:Date.now(),networkId:e,ownerId:t,oldValue:s,newValue:i}}static createRpcEventData(e,t,s,i,r,a){return{timestamp:Date.now(),clientId:s,rpcId:e,methodName:t,parameters:i,result:r,error:a}}static createMessageEventData(e,t,s,i=!0,r){const a=JSON.stringify(s).length;return{timestamp:Date.now(),clientId:r,messageId:e,messageType:t,payload:s,reliable:i,size:a}}static createConnectionEventData(e,t,s,i){return{timestamp:Date.now(),clientId:e,address:t,reason:s,reconnectAttempt:i}}static createRoomEventData(e,t,s,i){return{timestamp:Date.now(),roomId:e,playerId:t,playerCount:s,maxPlayers:i}}static createPerformanceEventData(e,t,s,i,r){return{timestamp:Date.now(),clientId:r,metric:e,value:t,threshold:s,duration:i}}}class w extends t.Component{constructor(){super(...arguments),this.eventEmitter=new t.Emitter,this.networkId=0,this.ownerId="",this.authority=e.AuthorityType.Server,this.syncRate=20,this.scope=e.NetworkScope.Room,this.isLocalPlayer=!1,this.syncEnabled=!0,this.priority=0,this.distanceThreshold=100,this.lastSyncTime=0,this.visible=!0}getSyncWeight(t){let s=this.priority;if(void 0!==t&&this.scope===e.NetworkScope.Nearby){s*=Math.max(0,1-t/this.distanceThreshold)}return s}shouldSyncToClient(t,s){if(!this.syncEnabled||!this.visible)return!1;switch(this.scope){case e.NetworkScope.Global:case e.NetworkScope.Room:return!0;case e.NetworkScope.Owner:return t===this.ownerId;case e.NetworkScope.Nearby:return void 0!==s&&s<=this.distanceThreshold;case e.NetworkScope.Custom:return!!this.customSyncFilter&&this.customSyncFilter(t);default:return!1}}hasAuthority(t){switch(this.authority){case e.AuthorityType.Server:return!1;case e.AuthorityType.Client:return t===this.ownerId;case e.AuthorityType.Shared:return!0;default:return!1}}setOwner(t){const s=this.ownerId;this.ownerId=t,this.emitEvent(e.NetworkEventType.IDENTITY_OWNER_CHANGED,T.createIdentityEventData(this.networkId,t,s,t))}setAuthority(t){const s=this.authority;this.authority=t,this.emitEvent(e.NetworkEventType.IDENTITY_AUTHORITY_CHANGED,T.createIdentityEventData(this.networkId,this.ownerId,s,t))}setSyncEnabled(t){const s=this.syncEnabled;this.syncEnabled=t;const i=t?e.NetworkEventType.IDENTITY_SYNC_ENABLED:e.NetworkEventType.IDENTITY_SYNC_DISABLED;this.emitEvent(i,T.createIdentityEventData(this.networkId,this.ownerId,s,t))}setSyncRate(t){const s=this.syncRate;this.syncRate=t,this.emitEvent(e.NetworkEventType.SYNC_RATE_CHANGED,T.createIdentityEventData(this.networkId,this.ownerId,s,t))}addEventListener(e,t){this.eventEmitter.addObserver(e,t,this)}removeEventListener(e,t){this.eventEmitter.removeObserver(e,t)}emitEvent(e,t){this.eventEmitter.emit(e,t)}onPropertyChanged(t){this.addEventListener(e.NetworkEventType.IDENTITY_PROPERTY_CHANGED,t)}onOwnerChanged(t){this.addEventListener(e.NetworkEventType.IDENTITY_OWNER_CHANGED,t)}onAuthorityChanged(t){this.addEventListener(e.NetworkEventType.IDENTITY_AUTHORITY_CHANGED,t)}onSyncStateChanged(t){this.addEventListener(e.NetworkEventType.IDENTITY_SYNC_ENABLED,t),this.addEventListener(e.NetworkEventType.IDENTITY_SYNC_DISABLED,t)}getDebugInfo(){return{networkId:this.networkId,ownerId:this.ownerId,authority:this.authority,scope:this.scope,syncRate:this.syncRate,priority:this.priority,syncEnabled:this.syncEnabled,visible:this.visible,lastSyncTime:this.lastSyncTime}}dispose(){this.eventEmitter.dispose()}}e.ErrorSeverity=void 0,(m=e.ErrorSeverity||(e.ErrorSeverity={})).Low="low",m.Medium="medium",m.High="high",m.Critical="critical",e.RecoveryStrategy=void 0,(y=e.RecoveryStrategy||(e.RecoveryStrategy={})).Ignore="ignore",y.Retry="retry",y.Reconnect="reconnect",y.Restart="restart",y.Escalate="escalate";class S{constructor(){this.name="none",this.version="1.0.0",this.supportsAsync=!1}compress(e){return new Uint8Array(e)}decompress(e){return new Uint8Array(e)}}class E{constructor(){this.name="lz-string",this.version="1.0.0",this.supportsAsync=!1}compress(e){if(0===e.length)return new Uint8Array(0);const t={};let s=256;for(let e=0;e<256;e++)t[String(e)]=e;let i=String(e[0]);const r=[];for(let a=1;a<e.length;a++){const n=String(e[a]),o=i+","+n;if(void 0!==t[o])i=o;else if(r.push(t[i]),t[o]=s++,i=n,s>=32768){s=256;const e={};for(let t=0;t<256;t++)e[String(t)]=t;Object.assign(t,e)}}return i&&r.push(t[i]),this.numbersToUint8Array(r)}decompress(e){if(0===e.length)return new Uint8Array(0);const t=this.uint8ArrayToNumbers(e);if(0===t.length)return new Uint8Array(0);const s={};let i=256;for(let e=0;e<256;e++)s[e]=[e];let r=s[t[0]];const a=[...r];for(let e=1;e<t.length;e++){const n=t[e];let o;if(void 0!==s[n])o=s[n];else{if(n!==i)throw new Error("LZ解压缩错误:无效的压缩数据");o=[...r,r[0]]}if(a.push(...o),s[i++]=[...r,o[0]],r=o,i>=32768){i=256;const e={};for(let t=0;t<256;t++)e[t]=[t];Object.assign(s,e)}}return new Uint8Array(a)}numbersToUint8Array(e){const t=[];for(const s of e)s<128?t.push(s):s<16384?(t.push(128|127&s),t.push(s>>7&127)):(t.push(128|127&s),t.push(128|s>>7&127),t.push(s>>14&127));return new Uint8Array(t)}uint8ArrayToNumbers(e){const t=e,s=[];for(let e=0;e<t.length;e++){const i=t[e];if(128&i){let r=127&i;if(e++,e<t.length){const s=t[e];if(r|=(127&s)<<7,128&s&&(e++,e<t.length)){r|=(127&t[e])<<14}}s.push(r)}else s.push(i)}return s}}class v{constructor(e={}){this.logger=t.createLogger("MessageCompressor"),this.algorithms=new Map,this.config={defaultAlgorithm:"none",threshold:1024,enableAsync:!0,level:6,chunkSize:65536,enableStats:!0,...e},this.stats={totalCompressions:0,totalDecompressions:0,totalOriginalBytes:0,totalCompressedBytes:0,averageCompressionRatio:1,averageCompressionTime:0,averageDecompressionTime:0,algorithmUsage:{}},this.registerAlgorithm(new S),this.registerAlgorithm(new E)}registerAlgorithm(e){this.algorithms.has(e.name)&&this.logger.warn(`压缩算法 '${e.name}' 已存在,将被覆盖`),this.algorithms.set(e.name,e),this.stats.algorithmUsage[e.name]=0,this.logger.info(`注册压缩算法: ${e.name} v${e.version}`)}unregisterAlgorithm(e){if("none"===e)return this.logger.warn("无法注销默认的无压缩算法"),!1;const t=this.algorithms.delete(e);return t&&(delete this.stats.algorithmUsage[e],this.logger.info(`注销压缩算法: ${e}`)),t}getRegisteredAlgorithms(){return Array.from(this.algorithms.keys())}hasAlgorithm(e){return this.algorithms.has(e)}async compress(e,t){const s=performance.now(),i="string"==typeof e?(new TextEncoder).encode(e):new Uint8Array(e),r=i.length,a=t||this.config.defaultAlgorithm,n=this.algorithms.get(a);if(!n)throw new Error(`未找到压缩算法: ${a}`);try{let e,t=!1;r<this.config.threshold||"none"===a?e=new Uint8Array(i):(e=this.config.enableAsync&&n.supportsAsync&&n.compressAsync?await n.compressAsync(i):n.compress(i),t=!0);const o=performance.now()-s,c=(e.byteLength,{magic:"MCF0",version:1,algo:a,originalSize:r,flags:0}),l=this.encodeContainerHeader(c,e),h=l.byteLength,d=r>0?h/r:1;this.config.enableStats&&this.updateCompressionStats(a,r,h,o);const u={data:l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength),originalSize:r,compressedSize:h,compressionRatio:d,compressionTime:o,algorithm:a,wasCompressed:t};return this.logger.debug(`压缩完成: ${r}B -> ${h}B (${(100*d).toFixed(1)}%) 用时 ${o.toFixed(2)}ms, 算法: ${a}`),u}catch(e){throw this.logger.error(`压缩失败 (${a}):`,e),e}}async decompress(e){const t=performance.now(),s=e.byteLength,i=new Uint8Array(e);if(!this.isContainerFormat(i))throw new Error("无效的压缩数据格式,缺少容器头");const r=this.decodeContainerHeader(i),{header:a,payload:n}=r,o=this.algorithms.get(a.algo);if(!o)throw new Error(`未找到解压缩算法: ${a.algo}`);try{let e;if(e=this.config.enableAsync&&o.supportsAsync&&o.decompressAsync?await o.decompressAsync(n):o.decompress(n),e.length!==a.originalSize)throw new Error(`解压缩大小不匹配: 期望 ${a.originalSize}B, 实际 ${e.length}B`);const i=e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),r=performance.now()-t,c=i.byteLength;this.config.enableStats&&this.updateDecompressionStats(a.algo,r);const l={data:i,compressedSize:s,decompressedSize:c,decompressionTime:r,algorithm:a.algo};return this.logger.debug(`解压缩完成: ${s}B -> ${c}B 用时 ${r.toFixed(2)}ms, 算法: ${a.algo}`),l}catch(e){throw this.logger.error(`解压缩失败 (${a.algo}):`,e),e}}getStats(){return{...this.stats}}resetStats(){this.stats={totalCompressions:0,totalDecompressions:0,totalOriginalBytes:0,totalCompressedBytes:0,averageCompressionRatio:1,averageCompressionTime:0,averageDecompressionTime:0,algorithmUsage:{}};for(const e of this.algorithms.keys())this.stats.algorithmUsage[e]=0}updateConfig(e){Object.assign(this.config,e),this.logger.info("压缩器配置已更新")}getConfig(){return{...this.config}}updateCompressionStats(e,t,s,i){this.stats.totalCompressions++,this.stats.totalOriginalBytes+=t,this.stats.totalCompressedBytes+=s,this.stats.algorithmUsage[e]++,this.stats.averageCompressionRatio=this.stats.totalOriginalBytes>0?this.stats.totalCompressedBytes/this.stats.totalOriginalBytes:1,this.stats.averageCompressionTime=(this.stats.averageCompressionTime*(this.stats.totalCompressions-1)+i)/this.stats.totalCompressions}updateDecompressionStats(e,t){this.stats.totalDecompressions++,this.stats.averageDecompressionTime=(this.stats.averageDecompressionTime*(this.stats.totalDecompressions-1)+t)/this.stats.totalDecompressions}encodeContainerHeader(e,t){const s=(new TextEncoder).encode(e.algo);if(s.length>255)throw new Error(`算法名称过长: ${e.algo.length} > 255`);const i=6+s.length+4+1+t.length,r=new Uint8Array(i);let a=0;r[a++]=77,r[a++]=67,r[a++]=70,r[a++]=48,r[a++]=e.version,r[a++]=s.length,r.set(s,a),a+=s.length;const n=new ArrayBuffer(4);return new DataView(n).setUint32(0,e.originalSize,!0),r.set(new Uint8Array(n),a),a+=4,r[a++]=e.flags,r.set(t,a),r}decodeContainerHeader(e){if(e.length<11)throw new Error("数据太小,无法包含有效的容器头");let t=0;const s=String.fromCharCode(e[t],e[t+1],e[t+2],e[t+3]);if("MCF0"!==s)throw new Error(`无效的魔数: ${s},期望: MCF0`);t+=4;const i=e[t++];if(1!==i)throw new Error(`不支持的版本: ${i},期望: 1`);const r=e[t++];if(t+r>e.length)throw new Error("算法名称长度超出数据边界");const a=new TextDecoder,n=e.slice(t,t+r),o=a.decode(n);if(t+=r,t+4>e.length)throw new Error("原始大小字段超出数据边界");const c=e.slice(t,t+4),l=new DataView(c.buffer,c.byteOffset,4).getUint32(0,!0);if(t+=4,t>=e.length)throw new Error("标志位字段超出数据边界");return{header:{magic:"MCF0",version:i,algo:o,originalSize:l,flags:e[t++]},headerSize:t,payload:e.slice(t)}}isContainerFormat(e){return e.length>=4&&77===e[0]&&67===e[1]&&70===e[2]&&48===e[3]}}const C=new v;const D=Symbol("SyncVarMetadata"),I={mode:e.SyncMode.All,syncRate:100,authority:e.AuthorityType.Server,scope:e.NetworkScope.Global,threshold:.001,compression:!0,priority:5,interpolation:!1,customSerializer:e=>e,customDeserializer:e=>e,onChanged:()=>{}};function R(e,t){if(e===t)return!0;if(null==e||null==t)return e===t;if(typeof e!=typeof t)return!1;if("object"!=typeof e)return e===t;const s=Object.keys(e),i=Object.keys(t);if(s.length!==i.length)return!1;for(const r of s){if(!i.includes(r))return!1;if(!R(e[r],t[r]))return!1}return!0}function b(e){return e&&e.constructor&&e.constructor[D]||new Map}function M(e){return b(e).size>0}function O(e){const t=b(e),s=new Map;for(const[e,i]of t)i.isDirty&&s.set(e,i);return s}function N(e){const t=b(e);for(const e of t.values())e.isDirty=!1,e.lastSyncTime=Date.now(),e.syncCount++}const A=Symbol("rpc:metadata"),z=Symbol("rpc:methods");function _(e){const t=Reflect.getMetadata(z,e)||[],s=e.prototype;return t.map(t=>{const i=Reflect.getMetadata(A,s,t);if(!i)throw new Error(`RPC元数据未找到: ${e.name}.${t}`);return i})}function k(e,t){return Reflect.getMetadata(A,e,t)}class L{static validateCall(e,t,s){return t.length!==e.paramTypes.length?{valid:!1,error:`参数数量不匹配,期望 ${e.paramTypes.length} 个,实际 ${t.length} 个`}:e.options.requireAuth&&!s?{valid:!1,error:"该方法需要身份验证"}:{valid:!0}}static validateMethodDefinition(e){return e.methodName&&"string"==typeof e.methodName?e.options.timeout&&e.options.timeout<=0?{valid:!1,error:"超时时间必须大于0"}:void 0!==e.options.priority&&(e.options.priority<0||e.options.priority>10)?{valid:!1,error:"优先级必须在0-10之间"}:{valid:!0}:{valid:!1,error:"方法名无效"}}}class x extends t.Emitter{constructor(){super()}on(e,t){return this.addObserver(e,t,void 0),this}once(e,t){const s=(...i)=>{t.apply(this,i),this.removeObserver(e,s)};return this.addObserver(e,s,void 0),this}off(e,t){return t?this.removeObserver(e,t):this.removeAllObservers(e),this}removeListener(e,t){return this.off(e,t)}removeAllListeners(e){return this.removeAllObservers(e),this}listenerCount(e){return this.getObserverCount(e)}emit(e,...t){return super.emit(e,...t),!0}}class P extends x{constructor(){super(),this.registeredInstances=new Map,this.dirtyInstances=new Set,this.instanceIdCounter=0,this.instanceIdMap=new WeakMap,this.stats={registeredInstances:0,dirtyInstances:0,totalSyncs:0,totalBytes:0,averageLatency:0,syncsPerSecond:0,lastSyncTime:0},this.autoSyncTimer=null,this.syncRate=100,this.autoSyncEnabled=!0,this.maxBatchSize=100,this.immediateSyncQueue=new Set,this.startAutoSync()}static getInstance(){return P.instance||(P.instance=new P),P.instance}registerInstance(e){if(!M(e))throw new Error("实例没有SyncVar属性,无法注册");if(this.instanceIdMap.has(e))return this.instanceIdMap.get(e);const t="syncvar_"+ ++this.instanceIdCounter;return this.registeredInstances.set(t,e),this.instanceIdMap.set(e,t),this.stats.registeredInstances=this.registeredInstances.size,this.emit("instanceRegistered",t,e),t}unregisterInstance(e){const t=this.instanceIdMap.get(e);return!!t&&(this.registeredInstances.delete(t),this.instanceIdMap.delete(e),this.dirtyInstances.delete(t),this.stats.registeredInstances=this.registeredInstances.size,this.stats.dirtyInstances=this.dirtyInstances.size,this.emit("instanceUnregistered",t),!0)}markInstanceDirty(e){const t=this.instanceIdMap.get(e);if(!t)return this.registerInstance(e),this.markInstanceDirty(e);this.dirtyInstances.add(t),this.stats.dirtyInstances=this.dirtyInstances.size}requestImmediateSync(e,t){const s=this.instanceIdMap.get(e);s&&(this.markInstanceDirty(e),this.immediateSyncQueue.add({instanceId:s,propertyKey:t}),this.processImmediateSyncs())}syncNow(){const e=[];this.processImmediateSyncs();for(const t of this.dirtyInstances){const s=this.createSyncBatch(t);s&&Object.keys(s.changes).length>0&&e.push(s)}return this.clearAllDirtyFlags(),this.stats.totalSyncs+=e.length,this.stats.lastSyncTime=Date.now(),e}setSyncRate(e){this.syncRate=Math.max(1,e),this.autoSyncEnabled&&this.restartAutoSync()}setAutoSyncEnabled(e){this.autoSyncEnabled=e,e?this.startAutoSync():this.stopAutoSync()}setMaxBatchSize(e){this.maxBatchSize=Math.max(1,e)}getStats(){return{...this.stats}}getInstanceId(e){return this.instanceIdMap.get(e)}getInstance(e){return this.registeredInstances.get(e)}getAllInstanceIds(){return Array.from(this.registeredInstances.keys())}isInstanceDirty(e){return this.dirtyInstances.has(e)}resetStats(){this.stats={...this.stats,totalSyncs:0,totalBytes:0,averageLatency:0,syncsPerSecond:0}}destroy(){this.stopAutoSync(),this.registeredInstances.clear(),this.dirtyInstances.clear(),this.instanceIdMap=new WeakMap,this.immediateSyncQueue.clear(),this.removeAllListeners(),P.instance=null}createSyncBatch(e){const t=this.registeredInstances.get(e);if(!t)return null;const s=O(t);if(0===s.size)return null;const i={},r={},a={},n={},o={};for(const[e,c]of s){const s=String(e);i[s]=t[e],r[s]=c.options.mode,a[s]=c.options.authority,n[s]=c.options.scope,o[s]=c.options.priority}return{instanceId:e,instanceType:t.constructor.name,changes:i,timestamp:Date.now(),syncModes:r,authorities:a,scopes:n,priorities:o}}processImmediateSyncs(){if(0===this.immediateSyncQueue.size)return;const e=[];for(const t of this.immediateSyncQueue){const s=this.createSyncBatch(t.instanceId);if(s&&Object.keys(s.changes).length>0)if(t.propertyKey){const i=String(t.propertyKey);if(void 0!==s.changes[i]){const t={...s,changes:{[i]:s.changes[i]},syncModes:{[i]:s.syncModes[i]},authorities:{[i]:s.authorities[i]},scopes:{[i]:s.scopes[i]},priorities:{[i]:s.priorities[i]}};e.push(t)}}else e.push(s)}this.immediateSyncQueue.clear();for(const t of e)this.emit("syncBatchReady",t),this.emit("syncCompleted",t.instanceId,Object.keys(t.changes).length)}clearAllDirtyFlags(){for(const e of this.dirtyInstances){const t=this.registeredInstances.get(e);t&&N(t)}this.dirtyInstances.clear(),this.stats.dirtyInstances=0}startAutoSync(){!this.autoSyncTimer&&this.autoSyncEnabled&&(this.autoSyncTimer=setInterval(()=>{try{const e=this.syncNow();for(const t of e)this.emit("syncBatchReady",t),this.emit("syncCompleted",t.instanceId,Object.keys(t.changes).length)}catch(e){this.emit("syncError",e)}},this.syncRate))}stopAutoSync(){this.autoSyncTimer&&(clearInterval(this.autoSyncTimer),this.autoSyncTimer=null)}restartAutoSync(){this.stopAutoSync(),this.startAutoSync()}}var H,$,j,U;P.instance=null,"undefined"!=typeof window&&(window.SyncVarManager=P.getInstance()),e.DeltaOperationType=void 0,(H=e.DeltaOperationType||(e.DeltaOperationType={})).ADD="add",H.MODIFY="modify",H.DELETE="delete",H.BATCH="batch",H.NOOP="noop";e.BandwidthWarningLevel=void 0,($=e.BandwidthWarningLevel||(e.BandwidthWarningLevel={})).Normal="normal",$.Warning="warning",$.Critical="critical";e.ReconnectionState=void 0,(j=e.ReconnectionState||(e.ReconnectionState={})).DISCONNECTED="disconnected",j.RECONNECTING="reconnecting",j.CONNECTED="connected",j.FAILED="failed",j.ABANDONED="abandoned";e.DataType=void 0,(U=e.DataType||(e.DataType={})).STATE_SNAPSHOT="state_snapshot",U.USER_SESSION="user_session",U.GAME_DATA="game_data",U.AUTH_TOKEN="auth_token",U.USER_PROFILE="user_profile",U.ADMIN_RECORD="admin_record",U.SECURITY_LOG="security_log",U.METRIC_DATA="metric_data";class V extends x{constructor(){super(),this.logger=t.createLogger("MemoryDataPersistence"),this.storage=new Map,this.transactions=new Map,this.startCleanupTimer()}async save(e,t,s,i){const r=this.buildKey(e,t),a={data:s,expiry:i?Date.now()+1e3*i:void 0};this.storage.set(r,a),this.emit("data:saved",e,t,s),this.logger.debug(`保存数据: ${r}`)}async load(e,t){const s=this.buildKey(e,t),i=this.storage.get(s);return i?i.expiry&&Date.now()>i.expiry?(this.storage.delete(s),null):(this.emit("data:loaded",e,t,i.data),i.data):null}async delete(e,t){const s=this.buildKey(e,t),i=this.storage.delete(s);return i&&(this.emit("data:deleted",e,t),this.logger.debug(`删除数据: ${s}`)),i}async exists(e,t){const s=this.buildKey(e,t),i=this.storage.get(s);return!!i&&(!(i.expiry&&Date.now()>i.expiry)||(this.storage.delete(s),!1))}async query(e,t={}){const s=`${e}:`,i=[];for(const[e,t]of this.storage.entries())if(e.startsWith(s)){if(t.expiry&&Date.now()>t.expiry){this.storage.delete(e);continue}const r=e.substring(s.length);i.push({key:r,data:t.data})}let r=i;t.filters&&(r=i.filter(e=>this.matchesFilters(e.data,t.filters))),t.sort&&t.sort.length>0&&(r=this.applySorting(r,t.sort));const a=t.offset||0,n=t.limit||r.length;return{data:r.slice(a,a+n).map(e=>e.data),total:r.length,page:Math.floor(a/(n||1))+1,pageSize:n,hasMore:a+n<r.length}}async batchSave(e,t,s){this.emit("batch:started","save",t.length);let i=0;const r=s?.batchSize||100;for(let a=0;a<t.length;a+=r){const n=t.slice(a,a+r);for(const r of n)await this.save(e,r.key,r.data,r.ttl),i++,s?.onProgress&&s.onProgress(i,t.length)}this.emit("batch:completed","save",i,0)}async batchLoad(e,t){const s=new Map;for(const i of t){const t=await this.load(e,i);null!==t&&s.set(i,t)}return s}async batchDelete(e,t){let s=0;for(const i of t)await this.delete(e,i)&&s++;return s}async beginTransaction(e){const t=this.generateTransactionId(),s=new Map(this.storage);return this.transactions.set(t,s),this.emit("transaction:started",t),this.logger.debug(`开始事务: ${t}`),t}async commitTransaction(e){if(!this.transactions.has(e))throw new Error(`Transaction not found: ${e}`);this.transactions.delete(e),this.emit("transaction:committed",e),this.logger.debug(`提交事务: ${e}`)}async rollbackTransaction(e){const t=this.transactions.get(e);if(!t)throw new Error(`Transaction not found: ${e}`);this.storage=t,this.transactions.delete(e),this.emit("transaction:rolled_back",e,"manual rollback"),this.logger.debug(`回滚事务: ${e}`)}async cleanup(){const e=Date.now();let t=0;for(const[s,i]of this.storage.entries())i.expiry&&e>i.expiry&&(this.storage.delete(s),t++);return this.logger.info(`清理过期数据: ${t} 项`),t}async getStats(){const t={};for(const s of Object.values(e.DataType))t[s]=0;for(const e of this.storage.keys()){const[s]=e.split(":");s in t&&t[s]++}return{totalItems:this.storage.size,itemsByType:t,storageSize:this.estimateSize(),lastCleanup:Date.now(),connectionStatus:"connected"}}async close(){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.storage.clear(),this.transactions.clear(),this.logger.info("内存存储已关闭")}buildKey(e,t){return`${e}:${t}`}matchesFilters(e,t){for(const[s,i]of Object.entries(t))if(e[s]!==i)return!1;return!0}applySorting(e,t){return e.sort((e,s)=>{for(const i of t){const t=e.data[i.field],r=s.data[i.field];let a=0;if(t<r?a=-1:t>r&&(a=1),0!==a)return"desc"===i.order?-a:a}return 0})}estimateSize(){let e=0;for(const[t,s]of this.storage.entries())e+=2*t.length,e+=2*JSON.stringify(s.data).length;return e}generateTransactionId(){return`tx_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}startCleanupTimer(){this.cleanupTimer=setInterval(()=>{this.cleanup().catch(e=>{this.emit("error","cleanup",e)})},3e5)}}class B extends x{constructor(e){super(),this.logger=t.createLogger("FileDataPersistence"),this.basePath=e;try{this.fs=require("fs").promises,this.path=require("path"),this.ensureDirectoryExists()}catch(e){throw this.logger.error("文件系统模块不可用:",e),new Error("File system not available in this environment")}}async save(e,t,s,i){const r=this.buildFilePath(e,t),a={data:s,expiry:i?Date.now()+1e3*i:void 0,savedAt:Date.now()};await this.fs.writeFile(r,JSON.stringify(a,null,2)),this.emit("data:saved",e,t,s),this.logger.debug(`保存文件: ${r}`)}async load(e,t){const s=this.buildFilePath(e,t);try{const i=await this.fs.readFile(s,"utf8"),r=JSON.parse(i);return r.expiry&&Date.now()>r.expiry?(await this.fs.unlink(s),null):(this.emit("data:loaded",e,t,r.data),r.data)}catch(e){if("ENOENT"===e.code)return null;throw e}}async delete(e,t){const s=this.buildFilePath(e,t);try{return await this.fs.unlink(s),this.emit("data:deleted",e,t),this.logger.debug(`删除文件: ${s}`),!0}catch(e){if("ENOENT"===e.code)return!1;throw e}}async exists(e,t){const s=this.buildFilePath(e,t);try{return(await this.fs.stat(s)).isFile()}catch(e){if("ENOENT"===e.code)return!1;throw e}}async query(e,t={}){const s=this.path.join(this.basePath,e),i=[];try{const t=await this.fs.readdir(s);for(const s of t)if(s.endsWith(".json")){const t=s.replace(".json",""),r=await this.load(e,t);null!==r&&i.push({key:t,data:r})}}catch(e){if("ENOENT"!==e.code)throw e}let r=i;t.filters&&(r=i.filter(e=>this.matchesFilters(e.data,t.filters))),t.sort&&t.sort.length>0&&(r=this.applySorting(r,t.sort));const a=t.offset||0,n=t.limit||r.length;return{data:r.slice(a,a+n).map(e=>e.data),total:r.length,page:Math.floor(a/(n||1))+1,pageSize:n,hasMore:a+n<r.length}}async batchSave(e,t,s){this.emit("batch:started","save",t.length);let i=0;const r=s?.batchSize||100;for(let a=0;a<t.length;a+=r){const n=t.slice(a,a+r);await Promise.all(n.map(async r=>{await this.save(e,r.key,r.data,r.ttl),i++,s?.onProgress&&s.onProgress(i,t.length)}))}this.emit("batch:completed","save",i,0)}async batchLoad(e,t){const s=new Map;return await Promise.all(t.map(async t=>{const i=await this.load(e,t);null!==i&&s.set(t,i)})),s}async batchDelete(e,t){let s=0;return await Promise.all(t.map(async t=>{await this.delete(e,t)&&s++})),s}async beginTransaction(){const e=this.generateTransactionId();return this.emit("transaction:started",e),e}async commitTransaction(e){this.emit("transaction:committed",e)}async rollbackTransaction(e){this.emit("transaction:rolled_back",e,"file system rollback not supported")}async cleanup(){let t=0;for(const s of Object.values(e.DataType)){const e=this.path.join(this.basePath,s);try{const s=await this.fs.readdir(e);for(const i of s)if(i.endsWith(".json")){const s=this.path.join(e,i),r=await this.fs.readFile(s,"utf8"),a=JSON.parse(r);a.expiry&&Date.now()>a.expiry&&(await this.fs.unlink(s),t++)}}catch(t){"ENOENT"!==t.code&&this.logger.warn(`清理目录失败 ${e}:`,t)}}return this.logger.info(`清理过期文件: ${t} 个`),t}async getStats(){const t={};let s=0,i=0;for(const r of Object.values(e.DataType)){t[r]=0;const e=this.path.join(this.basePath,r);try{const a=await this.fs.readdir(e);for(const n of a)if(n.endsWith(".json")){t[r]++,s++;const a=this.path.join(e,n);i+=(await this.fs.stat(a)).size}}catch(t){"ENOENT"!==t.code&&this.logger.warn(`获取统计信息失败 ${e}:`,t)}}return{totalItems:s,itemsByType:t,storageSize:i,lastCleanup:Date.now(),connectionStatus:"connected"}}async close(){this.logger.info("文件存储已关闭")}buildFilePath(e,t){const s=this.path.join(this.basePath,e);return this.path.join(s,`${t}.json`)}async ensureDirectoryExists(){for(const t of Object.values(e.DataType)){const e=this.path.join(this.basePath,t);await this.fs.mkdir(e,{recursive:!0})}}matchesFilters(e,t){for(const[s,i]of Object.entries(t))if(e[s]!==i)return!1;return!0}applySorting(e,t){return e.sort((e,s)=>{for(const i of t){const t=e.data[i.field],r=s.data[i.field];let a=0;if(t<r?a=-1:t>r&&(a=1),0!==a)return"desc"===i.order?-a:a}return 0})}generateTransactionId(){return`tx_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}class F{static create(e){switch(e.type){case"memory":return new V;case"file":const t=e.options?.basePath||"./data";return new B(t);case"database":throw new Error("Database persistence not implemented yet");case"redis":throw new Error("Redis persistence not implemented yet");default:throw new Error(`Unsupported storage type: ${e.type}`)}}}F.logger=t.createLogger("DataPersistenceFactory"),e.AdvancedSerializer=class extends x{constructor(){super(),this.logger=t.createLogger("AdvancedSerializer"),this.typeRegistry=new Map,this.nextTypeId=1e3,this.version={major:1,minor:0,patch:0},this.builtinSerializers=new Map,this.initializeBuiltinSerializers()}registerTypeSerializer(e,t,s){const i={typeName:e,typeId:this.nextTypeId++,version:t.getVersion(),serializer:t,dependencies:s};this.typeRegistry.set(e,i),this.emit("type:registered",i),this.logger.info(`注册类型序列化器: ${e} (ID: ${i.typeId})`)}serialize(e,t={}){const s=Date.now(),i={version:this.version,includeMetadata:!0,enableCompression:!1,referenceMap:new Map,circularRefs:new Set,customSerializers:new Map(Array.from(this.typeRegistry.entries()).map(([e,t])=>[e,t.serializer])),options:{includePrivateFields:!1,includeGetters:!1,maxDepth:10,enableTypeInference:!0,preserveInstanceTypes:!0,...t}};this.emit("serialization:start",i);try{const t=this.serializeObject(e,i,""),r=Date.now()-s,a=JSON.stringify(t),n=JSON.stringify(e).length,o=a.length,c={success:!0,data:t,metadata:{originalSize:n,serializedSize:o,compressionRatio:n>0?o/n:1,serializationTime:r,objectCount:i.referenceMap.size,typeCount:new Set(Array.from(i.referenceMap.keys()).map(e=>"object"==typeof e&&null!==e&&e.constructor?e.constructor.name:typeof e)).size}};return this.emit("serialization:complete",c),c}catch(e){const t=e instanceof Error?e.message:"Unknown serialization error";return this.emit("serialization:error",t,i),{success:!1,error:t,metadata:{originalSize:0,serializedSize:0,compressionRatio:0,serializationTime:Date.now()-s,objectCount:0,typeCount:0}}}}deserialize(e,t={}){const s=Date.now(),i={version:this.version,referenceMap:new Map,customSerializers:new Map(Array.from(this.typeRegistry.entries()).map(([e,t])=>[e,t.serializer])),typeRegistry:this.typeRegistry,options:{strictTypeChecking:!0,allowVersionMismatch:!1,createMissingTypes:!1,validateReferences:!0,repairCircularRefs:!0,...t}};this.emit("deserialization:start",i);try{const t=this.deserializeObject(e,i),r={success:!0,data:t,metadata:{deserializationTime:Date.now()-s,objectCount:i.referenceMap.size,referencesResolved:i.referenceMap.size,circularRefsRepaired:0}};return this.emit("deserialization:complete",r),r}catch(e){const t=e instanceof Error?e.message:"Unknown deserialization error";return this.emit("deserialization:error",t,i),{success:!1,errors:[t],metadata:{deserializationTime:Date.now()-s,objectCount:0,referencesResolved:0,circularRefsRepaired:0}}}}createIncrementalUpdate(e,t){const s=this.calculateChanges(e,t);return{updateId:this.generateId(),timestamp:Date.now(),baseVersion:e.__id,changes:s,metadata:{changeCount:s.length,affectedObjects:[...new Set(s.map(e=>e.objectId).filter(e=>Boolean(e)))],size:JSON.stringify(s).length}}}applyIncrementalUpdate(e,t){const s=JSON.parse(JSON.stringify(e));for(const e of t.changes)this.applyChange(s,e);return s}serializeObject(e,t,s,i=0){if(i>=t.options.maxDepth)return{__type:"MaxDepthExceeded",__version:t.version,data:{path:s}};if(t.circularRefs.has(e)){this.emit("circular:reference:detected",s,e);const i=t.referenceMap.get(e);return{__type:"CircularReference",__version:t.version,data:{refId:i}}}if(null===e||"object"!=typeof e)return{__type:typeof e,__version:t.version,data:{value:e}};t.circularRefs.add(e);try{const r=e.constructor.name,a=this.generateId();t.referenceMap.set(e,a);const n=this.getCustomSerializer(r,t);if(n){const s=n.serialize(e,t);return s.__id=a,s}return this.serializeDefaultObject(e,t,s,i+1,a)}finally{t.circularRefs.delete(e)}}deserializeObject(e,t){if(!this.isVersionCompatible(e.__version,t.version)&&!t.options.allowVersionMismatch)throw new Error(`Version mismatch: ${JSON.stringify(e.__version)} vs ${JSON.stringify(t.version)}`);switch(e.__type){case"CircularReference":const s=e.data.refId;return t.referenceMap.get(s);case"MaxDepthExceeded":throw new Error(`Max depth exceeded at path: ${e.data.path}`);case"string":case"number":case"boolean":case"undefined":return e.data.value;case"null":return null}const s=t.customSerializers.get(e.__type);if(s){const i=s.deserialize(e,t);return e.__id&&t.referenceMap.set(e.__id,i),i}return this.deserializeDefaultObject(e,t)}serializeDefaultObject(e,t,s,i,r){const a={},n=e.constructor.name;for(const r in e){if(!e.hasOwnProperty(r))continue;if(t.options.excludeFields?.includes(r))continue;if(t.options.includeOnlyFields&&!t.options.includeOnlyFields.includes(r))continue;const n=e[r],o=s?`${s}.${r}`:r;try{a[r]=this.serializeObject(n,t,o,i)}catch(e){this.logger.warn(`序列化字段失败: ${o}`,e);continue}}return{__type:n,__version:t.version,__id:r,data:a}}deserializeDefaultObject(e,t){const s={};e.__id&&t.referenceMap.set(e.__id,s);for(const i in e.data)try{s[i]=this.deserializeObject(e.data[i],t)}catch(e){this.logger.warn(`反序列化字段失败: ${i}`,e);continue}return s}getCustomSerializer(e,t){const s=this.typeRegistry.get(e);return s?.serializer}isVersionCompatible(e,t){return e.major===t.major}calculateChanges(e,t){const s=[];return JSON.stringify(e)!==JSON.stringify(t)&&s.push({type:"modify",path:"",oldValue:e,newValue:t}),s}applyChange(e,t){if("modify"===t.type)""===t.path&&Object.assign(e,t.newValue)}initializeBuiltinSerializers(){this.registerTypeSerializer("Array",{serialize:(e,t)=>({__type:"Array",__version:this.version,data:{items:e.map((e,s)=>this.serializeObject(e,t,`[${s}]`,0))}}),deserialize:(e,t)=>e.data.items.map(e=>this.deserializeObject(e,t)),getVersion:()=>({major:1,minor:0,patch:0})}),this.registerTypeSerializer("Date",{serialize:e=>({__type:"Date",__version:this.version,data:{timestamp:e.getTime()}}),deserialize:e=>new Date(e.data.timestamp),getVersion:()=>({major:1,minor:0,patch:0})}),this.registerTypeSerializer("Map",{serialize:(e,t)=>({__type:"Map",__version:this.version,data:{entries:Array.from(e.entries()).map(([e,s],i)=>[this.serializeObject(e,t,`[${i}].key`,0),this.serializeObject(s,t,`[${i}].value`,0)])}}),deserialize:(e,t)=>{const s=new Map;for(const[i,r]of e.data.entries){const e=this.deserializeObject(i,t),a=this.deserializeObject(r,t);s.set(e,a)}return s},getVersion:()=>({major:1,minor:0,patch:0})})}generateId(){return`${Date.now()}_${Math.random().toString(36).substr(2,9)}`}},e.BandwidthMonitor=class extends x{constructor(s={}){super(),this.logger=t.createLogger("BandwidthMonitor"),this.samples=[],this.currentWarningLevel=e.BandwidthWarningLevel.Normal,this.monitorTimer=null,this.stats={currentUpload:0,currentDownload:0,averageUpload:0,averageDownload:0,peakUpload:0,peakDownload:0,totalUpload:0,totalDownload:0,currentPacketRate:0,averageLatency:0,latencyJitter:0,utilization:0},this.lastStatsTime=Date.now(),this.cumulativeBytesIn=0,this.cumulativeBytesOut=0,this.cumulativePacketsIn=0,this.cumulativePacketsOut=0,this.config={monitorInterval:1e3,sampleWindowSize:60,warningThreshold:.8,criticalThreshold:.95,enableAdaptive:!0,adaptiveFactor:.1,...s},this.limits={uploadLimit:1048576,downloadLimit:1048576,enabled:!1},this.startMonitoring()}recordActivity(e,t,s=0,i=0,r=0){this.cumulativeBytesIn+=e,this.cumulativeBytesOut+=t,this.cumulativePacketsIn+=s,this.cumulativePacketsOut+=i,this.stats.totalUpload+=t,this.stats.totalDownload+=e}setBandwidthLimits(e){const t={...this.limits};Object.assign(this.limits,e),this.logger.info(`带宽限制已更新: 上行=${this.limits.uploadLimit}B/s, 下行=${this.limits.downloadLimit}B/s`),this.config.enableAdaptive&&this.emit("adaptiveAdjustment",t,this.limits)}getStats(){return{...this.stats}}getLimits(){return{...this.limits}}getWarningLevel(){return this.currentWarningLevel}isOverLimit(){return this.limits.enabled?{upload:this.stats.currentUpload>this.limits.uploadLimit,download:this.stats.currentDownload>this.limits.downloadLimit}:{upload:!1,download:!1}}getRecommendedSendSize(){if(!this.limits.enabled)return 1/0;const e=this.stats.currentUpload/this.limits.uploadLimit;return e<this.config.warningThreshold?.1*this.limits.uploadLimit:e<this.config.criticalThreshold?.05*this.limits.uploadLimit:.01*this.limits.uploadLimit}getRecommendedDelay(){const e=Math.max(this.stats.currentUpload/this.limits.uploadLimit,this.stats.currentDownload/this.limits.downloadLimit);return e<this.config.warningThreshold?0:e<this.config.criticalThreshold?100:500}resetStats(){this.stats={currentUpload:0,currentDownload:0,averageUpload:0,averageDownload:0,peakUpload:0,peakDownload:0,totalUpload:0,totalDownload:0,currentPacketRate:0,averageLatency:0,latencyJitter:0,utilization:0},this.samples.length=0,this.cumulativeBytesIn=0,this.cumulativeBytesOut=0,this.cumulativePacketsIn=0,this.cumulativePacketsOut=0,this.lastStatsTime=Date.now()}updateConfig(e){Object.assign(this.config,e),void 0!==e.monitorInterval&&this.restartMonitoring()}destroy(){this.stopMonitoring(),this.samples.length=0,this.removeAllListeners()}startMonitoring(){this.monitorTimer||(this.monitorTimer=setInterval(()=>{this.updateStats()},this.config.monitorInterval))}stopMonitoring(){this.monitorTimer&&(clearInterval(this.monitorTimer),this.monitorTimer=null)}restartMonitoring(){this.stopMonitoring(),this.startMonitoring()}updateStats(){const e=Date.now(),t=(e-this.lastStatsTime)/1e3;if(t<=0)return;const s=this.cumulativeBytesOut/t,i=this.cumulativeBytesIn/t,r=(this.cumulativePacketsIn+this.cumulativePacketsOut)/t,a={timestamp:e,bytesIn:this.cumulativeBytesIn,bytesOut:this.cumulativeBytesOut,packetsIn:this.cumulativePacketsIn,packetsOut:this.cumulativePacketsOut,latency:0};this.samples.push(a),this.samples.length>this.config.sampleWindowSize&&this.samples.shift(),this.stats.currentUpload=s,this.stats.currentDownload=i,this.stats.currentPacketRate=r,this.stats.peakUpload=Math.max(this.stats.peakUpload,s),this.stats.peakDownload=Math.max(this.stats.peakDownload,i),this.calculateAverages(),this.calculateUtilization(),this.checkLimits(),this.checkWarningLevel(),this.config.enableAdaptive&&this.performAdaptiveAdjustment(),this.cumulativeBytesIn=0,this.cumulativeBytesOut=0,this.cumulativePacketsIn=0,this.cumulativePacketsOut=0,this.lastStatsTime=e,this.emit("bandwidthChanged",this.stats)}calculateAverages(){if(0===this.samples.length)return;let e=0,t=0,s=0;for(let i=1;i<this.samples.length;i++){const r=this.samples[i-1],a=this.samples[i],n=(a.timestamp-r.timestamp)/1e3;n>0&&(e+=(a.bytesOut-r.bytesOut)/n,t+=(a.bytesIn-r.bytesIn)/n,s+=a.latency)}const i=this.samples.length-1;i>0&&(this.stats.averageUpload=e/i,this.stats.averageDownload=t/i,this.stats.averageLatency=s/this.samples.length),this.calculateLatencyJitter()}calculateLatencyJitter(){if(this.samples.length<2)return;let e=0,t=0;for(let s=1;s<this.samples.length;s++){e+=Math.abs(this.samples[s].latency-this.samples[s-1].latency),t++}this.stats.latencyJitter=t>0?e/t:0}calculateUtilization(){if(!this.limits.enabled)return void(this.stats.utilization=0);const e=this.stats.currentUpload/this.limits.uploadLimit,t=this.stats.currentDownload/this.limits.downloadLimit;this.stats.utilization=Math.max(e,t)}checkLimits(){this.limits.enabled&&(this.stats.currentUpload>this.limits.uploadLimit&&this.emit("limitExceeded","upload",this.stats.currentUpload,this.limits.uploadLimit),this.stats.currentDownload>this.limits.downloadLimit&&this.emit("limitExceeded","download",this.stats.currentDownload,this.limits.downloadLimit))}checkWarningLevel(){let t=e.BandwidthWarningLevel.Normal;this.stats.utilization>=this.config.criticalThreshold?t=e.BandwidthWarningLevel.Critical:this.stats.utilization>=this.config.warningThreshold&&(t=e.BandwidthWarningLevel.Warning),t!==this.currentWarningLevel&&(this.currentWarningLevel=t,this.emit("warningLevelChanged",t,this.stats))}performAdaptiveAdjustment(){if(!this.limits.enabled||this.stats.utilization<this.config.warningThreshold)return;const e={...this.limits};this.stats.utilization>this.config.criticalThreshold?(this.limits.uploadLimit*=1-this.config.adaptiveFactor,this.limits.downloadLimit*=1-this.config.adaptiveFactor):this.stats.utilization<.5*this.config.warningThreshold&&(this.limits.uploadLimit*=1+.5*this.config.adaptiveFactor,this.limits.downloadLimit*=1+.5*this.config.adaptiveFactor),this.limits.uploadLimit===e.uploadLimit&&this.limits.downloadLimit===e.downloadLimit||this.emit("adaptiveAdjustment",e,this.limits)}},e.ClientRpc=function(t={}){return function(s,i,r){const a=s.constructor.name,n=String(i),o=Reflect.getMetadata("design:paramtypes",s,i)||[],c=Reflect.getMetadata("design:returntype",s,i),l={methodName:n,className:a,isServerRpc:!1,options:{reliable:!1,priority:3,target:e.RpcTarget.All,timeout:1e4,requireAuth:!1,rateLimit:30,...t},paramTypes:o.map(e=>e?.constructor?.name||"unknown"),returnType:c?.name||"unknown"};Reflect.defineMetadata(A,l,s,i);const h=Reflect.getMetadata(z,s.constructor)||[];h.push(n),Reflect.defineMetadata(z,h,s.constructor);const d=r.value;return r.value=async function(...e){return d.apply(this,e)},r}},e.DEFAULT_SYNCVAR_OPTIONS=I,e.DataPersistenceFactory=F,e.DeltaSync=class{constructor(e={}){this.logger=t.createLogger("DeltaSync"),this.versionHistory=new Map,this.versionCounters=new Map,this.deltaCache=new Map,this.pendingOperations=new Map,this.stats={totalDeltas:0,totalSize:0,compressionRatio:1,averageDeltaSize:0,cacheHitRate:0,mergedOperations:0},this.mergeTimers=new Map,this.config={enabled:!0,maxHistoryVersions:10,versionTimeout:3e4,compressionThreshold:100,enableSmartMerging:!0,mergeWindow:50,...e}}recordBaseline(e,t){if(!this.config.enabled)return 0;const s=this.getNextVersion(e),i={version:s,timestamp:Date.now(),data:this.deepClone(t),checksum:this.calculateChecksum(t)};return this.storeVersion(e,i),s}calculateDelta(e,t,s){if(!this.config.enabled)return null;const i=this.versionHistory.get(e);if(!i||0===i.size)return this.recordBaseline(e,t),null;let r;if(void 0!==s){const t=i.get(s);if(t)r=t;else{this.logger.warn(`未找到版本 ${s},使用最新版本`);const t=this.getLatestVersion(e);if(!t)return this.logger.error(`实例 ${e} 没有任何版本历史`),null;r=t}}else{const t=this.getLatestVersion(e);if(!t)return this.logger.error(`实例 ${e} 没有任何版本历史`),null;r=t}const a=this.getNextVersion(e),n=this.computeChanges(r.data,t),o=this.computeDeletions(r.data,t);if(0===Object.keys(n).length&&0===o.length)return null;const c={baseVersion:r.version,targetVersion:a,changes:n,deletions:o,metadata:{timestamp:Date.now(),size:this.estimateSize(n)+this.estimateSize(o),compressionRatio:1}};return this.recordBaseline(e,t),this.updateStats(c),c}applyDelta(e,t){if(!this.config.enabled)return null;const s=this.versionHistory.get(e);if(!s)return this.logger.error(`实例 ${e} 没有版本历史`),null;const i=s.get(t.baseVersion);if(!i)return this.logger.error(`未找到基线版本 ${t.baseVersion}`),null;const r=this.deepClone(i.data);for(const[e,s]of Object.entries(t.changes))this.setNestedProperty(r,e,s);for(const e of t.deletions)this.deleteNestedProperty(r,e);const a={version:t.targetVersion,timestamp:t.metadata.timestamp,data:this.deepClone(r),checksum:this.calculateChecksum(r)};return this.storeVersion(e,a),r}mergeOperations(t,s){if(!this.config.enableSmartMerging||s.length<=1)return s;const i=new Map;for(const e of s){const t=i.get(e.path);if(t){const s=this.mergeTwoOperations(t,e);i.set(e.path,s),this.stats.mergedOperations++}else i.set(e.path,e)}return Array.from(i.values()).filter(t=>t.type!==e.DeltaOperationType.NOOP)}scheduleOperation(e,t){if(!this.config.enableSmartMerging)return;let s=this.pendingOperations.get(e);s||(s=[],this.pendingOperations.set(e,s)),s.push(t);const i=this.mergeTimers.get(e);i&&clearTimeout(i);const r=setTimeout(()=>{this.flushPendingOperations(e)},this.config.mergeWindow);this.mergeTimers.set(e,r)}compressDelta(e){if(e.metadata.size<this.config.compressionThreshold)return e;const t=this.compressObject(e.changes),s=e.deletions,i=e.metadata.size,r=this.estimateSize(t)+this.estimateSize(s);return{...e,changes:t,deletions:s,metadata:{...e.metadata,size:r,compressionRatio:r/i}}}cleanup(){const e=Date.now();for(const[t,s]of this.versionHistory){const i=[];for(const[t,r]of s)e-r.timestamp>this.config.versionTimeout&&i.push(t);const r=Array.from(s.keys()).sort((e,t)=>t-e).slice(0,this.config.maxHistoryVersions);for(const e of i)r.includes(e)||s.delete(e);0===s.size&&(this.versionHistory.delete(t),this.versionCounters.delete(t))}this.deltaCache.clear()}getStats(){return{...this.stats}}resetStats(){this.stats={totalDeltas:0,totalSize:0,compressionRatio:1,averageDeltaSize:0,cacheHitRate:0,mergedOperations:0}}updateConfig(e){Object.assign(this.config,e)}destroy(){for(const e of this.mergeTimers.values())clearTimeout(e);this.versionHistory.clear(),this.versionCounters.clear(),this.deltaCache.clear(),this.pendingOperations.clear(),this.mergeTimers.clear()}getNextVersion(e){const t=(this.versionCounters.get(e)||0)+1;return this.versionCounters.set(e,t),t}storeVersion(e,t){let s=this.versionHistory.get(e);if(s||(s=new Map,this.versionHistory.set(e,s)),s.set(t.version,t),s.size>this.config.maxHistoryVersions){const e=Math.min(...Array.from(s.keys()));s.delete(e)}}getLatestVersion(e){const t=this.versionHistory.get(e);if(!t||0===t.size)return;const s=Math.max(...Array.from(t.keys()));return t.get(s)}computeChanges(e,t){const s={};for(const[i,r]of Object.entries(t)){const t=e[i];this.deepEqual(t,r)||(s[i]=r)}return s}computeDeletions(e,t){const s=[];for(const i of Object.keys(e))i in t||s.push(i);return s}mergeTwoOperations(t,s){const i={type:s.type,path:s.path,oldValue:t.oldValue,newValue:s.newValue,timestamp:s.timestamp};return t.type===e.DeltaOperationType.ADD&&s.type===e.DeltaOperationType.DELETE?{type:e.DeltaOperationType.NOOP,path:s.path,oldValue:void 0,newValue:void 0,timestamp:s.timestamp}:(t.type===e.DeltaOperationType.DELETE&&s.type===e.DeltaOperationType.ADD&&(i.type=e.DeltaOperationType.MODIFY,i.oldValue=t.oldValue),t.type===e.DeltaOperationType.MODIFY&&s.type===e.DeltaOperationType.DELETE&&(i.type=e.DeltaOperationType.DELETE,i.newValue=void 0),t.type===e.DeltaOperationType.MODIFY&&s.type===e.DeltaOperationType.MODIFY&&this.deepEqual(t.oldValue,s.newValue)?{type:e.DeltaOperationType.NOOP,path:s.path,oldValue:void 0,newValue:void 0,timestamp:s.timestamp}:i)}flushPendingOperations(e){const t=this.pendingOperations.get(e);t&&0!==t.length&&(this.mergeOperations(e,t),this.pendi