UNPKG

@esengine/network-shared

Version:

ECS Framework网络层 - 共享组件和协议

1 lines 117 kB
"use strict";var e,t,s,r,i,a,n,o,c,l,h,d,p,u,g,m=require("@esengine/ecs-framework");exports.MessageType=void 0,(e=exports.MessageType||(exports.MessageType={})).CONNECT="connect",e.DISCONNECT="disconnect",e.HEARTBEAT="heartbeat",e.SYNC_VAR="sync_var",e.SYNC_BATCH="sync_batch",e.SYNC_SNAPSHOT="sync_snapshot",e.RPC_CALL="rpc_call",e.RPC_RESPONSE="rpc_response",e.ENTITY_CREATE="entity_create",e.ENTITY_DESTROY="entity_destroy",e.ENTITY_UPDATE="entity_update",e.JOIN_ROOM="join_room",e.LEAVE_ROOM="leave_room",e.ROOM_STATE="room_state",e.GAME_EVENT="game_event",e.ERROR="error",e.WARNING="warning",e.INFO="info",exports.AuthorityType=void 0,(t=exports.AuthorityType||(exports.AuthorityType={})).Server="server",t.Client="client",t.Shared="shared",exports.NetworkScope=void 0,(s=exports.NetworkScope||(exports.NetworkScope={})).Global="global",s.Room="room",s.Owner="owner",s.Nearby="nearby",s.Custom="custom",exports.SyncMode=void 0,(r=exports.SyncMode||(exports.SyncMode={})).All="all",r.Owner="owner",r.Others="others",r.Nearby="nearby",r.Custom="custom",exports.RpcTarget=void 0,(i=exports.RpcTarget||(exports.RpcTarget={})).Server="server",i.Client="client",i.All="all",i.Others="others",i.Owner="owner",i.Nearby="nearby",exports.RoomState=void 0,(a=exports.RoomState||(exports.RoomState={})).Waiting="waiting",a.Playing="playing",a.Paused="paused",a.Finished="finished",exports.NetworkErrorType=void 0,(n=exports.NetworkErrorType||(exports.NetworkErrorType={})).CONNECTION_FAILED="connection_failed",n.CONNECTION_LOST="connection_lost",n.AUTHENTICATION_FAILED="authentication_failed",n.PERMISSION_DENIED="permission_denied",n.RATE_LIMITED="rate_limited",n.INVALID_MESSAGE="invalid_message",n.TIMEOUT="timeout",n.UNKNOWN="unknown",exports.ConnectionState=void 0,(o=exports.ConnectionState||(exports.ConnectionState={})).Disconnected="disconnected",o.Connecting="connecting",o.Connected="connected",o.Reconnecting="reconnecting",o.Failed="failed",exports.RpcErrorType=void 0,(c=exports.RpcErrorType||(exports.RpcErrorType={})).METHOD_NOT_FOUND="method_not_found",c.INVALID_ARGUMENTS="invalid_arguments",c.PERMISSION_DENIED="permission_denied",c.TIMEOUT="timeout",c.RATE_LIMITED="rate_limited",c.NETWORK_ERROR="network_error",c.SERVER_ERROR="server_error",c.CLIENT_ERROR="client_error",c.UNKNOWN="unknown",exports.RpcCallStatus=void 0,(l=exports.RpcCallStatus||(exports.RpcCallStatus={})).PENDING="pending",l.SENT="sent",l.PROCESSING="processing",l.COMPLETED="completed",l.FAILED="failed",l.TIMEOUT="timeout",l.CANCELLED="cancelled",exports.MessageIdGeneratorType=void 0,(h=exports.MessageIdGeneratorType||(exports.MessageIdGeneratorType={})).UUID="uuid",h.SNOWFLAKE="snowflake",h.SEQUENTIAL="sequential",h.TIMESTAMP="timestamp";class y{constructor(e=1,t=1){this.sequence=0,this.lastTimestamp=-1,this.workerId=e&(1<<y.WORKER_ID_BITS)-1,this.datacenterId=t&(1<<y.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<<y.SEQUENCE_BITS)-1,0===this.sequence)for(;e<=this.lastTimestamp;)e=Date.now()}else this.sequence=0;this.lastTimestamp=e;return(e-y.EPOCH<<22|this.datacenterId<<17|this.workerId<<12|this.sequence).toString()}}y.EPOCH=16409952e5,y.WORKER_ID_BITS=5,y.DATACENTER_ID_BITS=5,y.SEQUENCE_BITS=12;exports.NetworkEventType=void 0,(d=exports.NetworkEventType||(exports.NetworkEventType={})).CONNECTION_ESTABLISHED="network:connection:established",d.CONNECTION_LOST="network:connection:lost",d.CONNECTION_ERROR="network:connection:error",d.CONNECTION_TIMEOUT="network:connection:timeout",d.RECONNECTION_STARTED="network:reconnection:started",d.RECONNECTION_SUCCEEDED="network:reconnection:succeeded",d.RECONNECTION_FAILED="network:reconnection:failed",d.IDENTITY_CREATED="network:identity:created",d.IDENTITY_DESTROYED="network:identity:destroyed",d.IDENTITY_OWNER_CHANGED="network:identity:owner:changed",d.IDENTITY_AUTHORITY_CHANGED="network:identity:authority:changed",d.IDENTITY_SYNC_ENABLED="network:identity:sync:enabled",d.IDENTITY_SYNC_DISABLED="network:identity:sync:disabled",d.IDENTITY_PROPERTY_CHANGED="network:identity:property:changed",d.IDENTITY_VISIBLE_CHANGED="network:identity:visible:changed",d.SYNC_STARTED="network:sync:started",d.SYNC_COMPLETED="network:sync:completed",d.SYNC_FAILED="network:sync:failed",d.SYNC_RATE_CHANGED="network:sync:rate:changed",d.SYNC_PRIORITY_CHANGED="network:sync:priority:changed",d.RPC_CALL_SENT="network:rpc:call:sent",d.RPC_CALL_RECEIVED="network:rpc:call:received",d.RPC_RESPONSE_SENT="network:rpc:response:sent",d.RPC_RESPONSE_RECEIVED="network:rpc:response:received",d.RPC_ERROR="network:rpc:error",d.RPC_TIMEOUT="network:rpc:timeout",d.MESSAGE_SENT="network:message:sent",d.MESSAGE_RECEIVED="network:message:received",d.MESSAGE_QUEUED="network:message:queued",d.MESSAGE_DROPPED="network:message:dropped",d.MESSAGE_RETRY="network:message:retry",d.MESSAGE_ACKNOWLEDGED="network:message:acknowledged",d.ROOM_JOINED="network:room:joined",d.ROOM_LEFT="network:room:left",d.ROOM_CREATED="network:room:created",d.ROOM_DESTROYED="network:room:destroyed",d.ROOM_PLAYER_JOINED="network:room:player:joined",d.ROOM_PLAYER_LEFT="network:room:player:left",d.CLIENT_CONNECTED="network:client:connected",d.CLIENT_DISCONNECTED="network:client:disconnected",d.CLIENT_AUTHENTICATED="network:client:authenticated",d.CLIENT_KICKED="network:client:kicked",d.CLIENT_TIMEOUT="network:client:timeout",d.SERVER_STARTED="network:server:started",d.SERVER_STOPPED="network:server:stopped",d.SERVER_ERROR="network:server:error",d.SERVER_OVERLOADED="network:server:overloaded",d.DATA_SYNCHRONIZED="network:data:synchronized",d.DATA_CONFLICT="network:data:conflict",d.DATA_CORRUPTED="network:data:corrupted",d.DATA_VALIDATED="network:data:validated",d.BANDWIDTH_WARNING="network:bandwidth:warning",d.LATENCY_HIGH="network:latency:high",d.PACKET_LOSS_DETECTED="network:packet:loss:detected",d.PERFORMANCE_DEGRADED="network:performance:degraded",exports.NetworkEventPriority=void 0,(p=exports.NetworkEventPriority||(exports.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 f{static createIdentityEventData(e,t,s,r){return{timestamp:Date.now(),networkId:e,ownerId:t,oldValue:s,newValue:r}}static createRpcEventData(e,t,s,r,i,a){return{timestamp:Date.now(),clientId:s,rpcId:e,methodName:t,parameters:r,result:i,error:a}}static createMessageEventData(e,t,s,r=!0,i){const a=JSON.stringify(s).length;return{timestamp:Date.now(),clientId:i,messageId:e,messageType:t,payload:s,reliable:r,size:a}}static createConnectionEventData(e,t,s,r){return{timestamp:Date.now(),clientId:e,address:t,reason:s,reconnectAttempt:r}}static createRoomEventData(e,t,s,r){return{timestamp:Date.now(),roomId:e,playerId:t,playerCount:s,maxPlayers:r}}static createPerformanceEventData(e,t,s,r,i){return{timestamp:Date.now(),clientId:i,metric:e,value:t,threshold:s,duration:r}}}class T extends m.Component{constructor(){super(...arguments),this.eventEmitter=new m.Emitter,this.networkId=0,this.ownerId="",this.authority=exports.AuthorityType.Server,this.syncRate=20,this.scope=exports.NetworkScope.Room,this.isLocalPlayer=!1,this.syncEnabled=!0,this.priority=0,this.distanceThreshold=100,this.lastSyncTime=0,this.visible=!0}getSyncWeight(e){let t=this.priority;if(void 0!==e&&this.scope===exports.NetworkScope.Nearby){t*=Math.max(0,1-e/this.distanceThreshold)}return t}shouldSyncToClient(e,t){if(!this.syncEnabled||!this.visible)return!1;switch(this.scope){case exports.NetworkScope.Global:case exports.NetworkScope.Room:return!0;case exports.NetworkScope.Owner:return e===this.ownerId;case exports.NetworkScope.Nearby:return void 0!==t&&t<=this.distanceThreshold;case exports.NetworkScope.Custom:return!!this.customSyncFilter&&this.customSyncFilter(e);default:return!1}}hasAuthority(e){switch(this.authority){case exports.AuthorityType.Server:return!1;case exports.AuthorityType.Client:return e===this.ownerId;case exports.AuthorityType.Shared:return!0;default:return!1}}setOwner(e){const t=this.ownerId;this.ownerId=e,this.emitEvent(exports.NetworkEventType.IDENTITY_OWNER_CHANGED,f.createIdentityEventData(this.networkId,e,t,e))}setAuthority(e){const t=this.authority;this.authority=e,this.emitEvent(exports.NetworkEventType.IDENTITY_AUTHORITY_CHANGED,f.createIdentityEventData(this.networkId,this.ownerId,t,e))}setSyncEnabled(e){const t=this.syncEnabled;this.syncEnabled=e;const s=e?exports.NetworkEventType.IDENTITY_SYNC_ENABLED:exports.NetworkEventType.IDENTITY_SYNC_DISABLED;this.emitEvent(s,f.createIdentityEventData(this.networkId,this.ownerId,t,e))}setSyncRate(e){const t=this.syncRate;this.syncRate=e,this.emitEvent(exports.NetworkEventType.SYNC_RATE_CHANGED,f.createIdentityEventData(this.networkId,this.ownerId,t,e))}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(e){this.addEventListener(exports.NetworkEventType.IDENTITY_PROPERTY_CHANGED,e)}onOwnerChanged(e){this.addEventListener(exports.NetworkEventType.IDENTITY_OWNER_CHANGED,e)}onAuthorityChanged(e){this.addEventListener(exports.NetworkEventType.IDENTITY_AUTHORITY_CHANGED,e)}onSyncStateChanged(e){this.addEventListener(exports.NetworkEventType.IDENTITY_SYNC_ENABLED,e),this.addEventListener(exports.NetworkEventType.IDENTITY_SYNC_DISABLED,e)}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()}}exports.ErrorSeverity=void 0,(u=exports.ErrorSeverity||(exports.ErrorSeverity={})).Low="low",u.Medium="medium",u.High="high",u.Critical="critical",exports.RecoveryStrategy=void 0,(g=exports.RecoveryStrategy||(exports.RecoveryStrategy={})).Ignore="ignore",g.Retry="retry",g.Reconnect="reconnect",g.Restart="restart",g.Escalate="escalate";class w{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 S{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 r=String(e[0]);const i=[];for(let a=1;a<e.length;a++){const n=String(e[a]),o=r+","+n;if(void 0!==t[o])r=o;else if(i.push(t[r]),t[o]=s++,r=n,s>=32768){s=256;const e={};for(let t=0;t<256;t++)e[String(t)]=t;Object.assign(t,e)}}return r&&i.push(t[r]),this.numbersToUint8Array(i)}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 r=256;for(let e=0;e<256;e++)s[e]=[e];let i=s[t[0]];const a=[...i];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!==r)throw new Error("LZ解压缩错误:无效的压缩数据");o=[...i,i[0]]}if(a.push(...o),s[r++]=[...i,o[0]],i=o,r>=32768){r=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 r=t[e];if(128&r){let i=127&r;if(e++,e<t.length){const s=t[e];if(i|=(127&s)<<7,128&s&&(e++,e<t.length)){i|=(127&t[e])<<14}}s.push(i)}else s.push(r)}return s}}class E{constructor(e={}){this.logger=m.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 w),this.registerAlgorithm(new S)}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(),r="string"==typeof e?(new TextEncoder).encode(e):new Uint8Array(e),i=r.length,a=t||this.config.defaultAlgorithm,n=this.algorithms.get(a);if(!n)throw new Error(`未找到压缩算法: ${a}`);try{let e,t=!1;i<this.config.threshold||"none"===a?e=new Uint8Array(r):(e=this.config.enableAsync&&n.supportsAsync&&n.compressAsync?await n.compressAsync(r):n.compress(r),t=!0);const o=performance.now()-s,c=(e.byteLength,{magic:"MCF0",version:1,algo:a,originalSize:i,flags:0}),l=this.encodeContainerHeader(c,e),h=l.byteLength,d=i>0?h/i:1;this.config.enableStats&&this.updateCompressionStats(a,i,h,o);const p={data:l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength),originalSize:i,compressedSize:h,compressionRatio:d,compressionTime:o,algorithm:a,wasCompressed:t};return this.logger.debug(`压缩完成: ${i}B -> ${h}B (${(100*d).toFixed(1)}%) 用时 ${o.toFixed(2)}ms, 算法: ${a}`),p}catch(e){throw this.logger.error(`压缩失败 (${a}):`,e),e}}async decompress(e){const t=performance.now(),s=e.byteLength,r=new Uint8Array(e);if(!this.isContainerFormat(r))throw new Error("无效的压缩数据格式,缺少容器头");const i=this.decodeContainerHeader(r),{header:a,payload:n}=i,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 r=e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),i=performance.now()-t,c=r.byteLength;this.config.enableStats&&this.updateDecompressionStats(a.algo,i);const l={data:r,compressedSize:s,decompressedSize:c,decompressionTime:i,algorithm:a.algo};return this.logger.debug(`解压缩完成: ${s}B -> ${c}B 用时 ${i.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,r){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)+r)/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 r=6+s.length+4+1+t.length,i=new Uint8Array(r);let a=0;i[a++]=77,i[a++]=67,i[a++]=70,i[a++]=48,i[a++]=e.version,i[a++]=s.length,i.set(s,a),a+=s.length;const n=new ArrayBuffer(4);return new DataView(n).setUint32(0,e.originalSize,!0),i.set(new Uint8Array(n),a),a+=4,i[a++]=e.flags,i.set(t,a),i}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 r=e[t++];if(1!==r)throw new Error(`不支持的版本: ${r},期望: 1`);const i=e[t++];if(t+i>e.length)throw new Error("算法名称长度超出数据边界");const a=new TextDecoder,n=e.slice(t,t+i),o=a.decode(n);if(t+=i,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:r,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 v=new E;const C=Symbol("SyncVarMetadata"),D={mode:exports.SyncMode.All,syncRate:100,authority:exports.AuthorityType.Server,scope:exports.NetworkScope.Global,threshold:.001,compression:!0,priority:5,interpolation:!1,customSerializer:e=>e,customDeserializer:e=>e,onChanged:()=>{}};function I(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),r=Object.keys(t);if(s.length!==r.length)return!1;for(const i of s){if(!r.includes(i))return!1;if(!I(e[i],t[i]))return!1}return!0}function R(e){return e&&e.constructor&&e.constructor[C]||new Map}function b(e){return R(e).size>0}function M(e){const t=R(e),s=new Map;for(const[e,r]of t)r.isDirty&&s.set(e,r);return s}function x(e){const t=R(e);for(const e of t.values())e.isDirty=!1,e.lastSyncTime=Date.now(),e.syncCount++}const O=Symbol("rpc:metadata"),N=Symbol("rpc:methods");function A(e){const t=Reflect.getMetadata(N,e)||[],s=e.prototype;return t.map(t=>{const r=Reflect.getMetadata(O,s,t);if(!r)throw new Error(`RPC元数据未找到: ${e.name}.${t}`);return r})}function z(e,t){return Reflect.getMetadata(O,e,t)}class _{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 k extends m.Emitter{constructor(){super()}on(e,t){return this.addObserver(e,t,void 0),this}once(e,t){const s=(...r)=>{t.apply(this,r),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 L extends k{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 L.instance||(L.instance=new L),L.instance}registerInstance(e){if(!b(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(),L.instance=null}createSyncBatch(e){const t=this.registeredInstances.get(e);if(!t)return null;const s=M(t);if(0===s.size)return null;const r={},i={},a={},n={},o={};for(const[e,c]of s){const s=String(e);r[s]=t[e],i[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:r,timestamp:Date.now(),syncModes:i,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 r=String(t.propertyKey);if(void 0!==s.changes[r]){const t={...s,changes:{[r]:s.changes[r]},syncModes:{[r]:s.syncModes[r]},authorities:{[r]:s.authorities[r]},scopes:{[r]:s.scopes[r]},priorities:{[r]:s.priorities[r]}};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&&x(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 P,H,$,j;L.instance=null,"undefined"!=typeof window&&(window.SyncVarManager=L.getInstance()),exports.DeltaOperationType=void 0,(P=exports.DeltaOperationType||(exports.DeltaOperationType={})).ADD="add",P.MODIFY="modify",P.DELETE="delete",P.BATCH="batch",P.NOOP="noop";exports.BandwidthWarningLevel=void 0,(H=exports.BandwidthWarningLevel||(exports.BandwidthWarningLevel={})).Normal="normal",H.Warning="warning",H.Critical="critical";exports.ReconnectionState=void 0,($=exports.ReconnectionState||(exports.ReconnectionState={})).DISCONNECTED="disconnected",$.RECONNECTING="reconnecting",$.CONNECTED="connected",$.FAILED="failed",$.ABANDONED="abandoned";exports.DataType=void 0,(j=exports.DataType||(exports.DataType={})).STATE_SNAPSHOT="state_snapshot",j.USER_SESSION="user_session",j.GAME_DATA="game_data",j.AUTH_TOKEN="auth_token",j.USER_PROFILE="user_profile",j.ADMIN_RECORD="admin_record",j.SECURITY_LOG="security_log",j.METRIC_DATA="metric_data";class U extends k{constructor(){super(),this.logger=m.createLogger("MemoryDataPersistence"),this.storage=new Map,this.transactions=new Map,this.startCleanupTimer()}async save(e,t,s,r){const i=this.buildKey(e,t),a={data:s,expiry:r?Date.now()+1e3*r:void 0};this.storage.set(i,a),this.emit("data:saved",e,t,s),this.logger.debug(`保存数据: ${i}`)}async load(e,t){const s=this.buildKey(e,t),r=this.storage.get(s);return r?r.expiry&&Date.now()>r.expiry?(this.storage.delete(s),null):(this.emit("data:loaded",e,t,r.data),r.data):null}async delete(e,t){const s=this.buildKey(e,t),r=this.storage.delete(s);return r&&(this.emit("data:deleted",e,t),this.logger.debug(`删除数据: ${s}`)),r}async exists(e,t){const s=this.buildKey(e,t),r=this.storage.get(s);return!!r&&(!(r.expiry&&Date.now()>r.expiry)||(this.storage.delete(s),!1))}async query(e,t={}){const s=`${e}:`,r=[];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 i=e.substring(s.length);r.push({key:i,data:t.data})}let i=r;t.filters&&(i=r.filter(e=>this.matchesFilters(e.data,t.filters))),t.sort&&t.sort.length>0&&(i=this.applySorting(i,t.sort));const a=t.offset||0,n=t.limit||i.length;return{data:i.slice(a,a+n).map(e=>e.data),total:i.length,page:Math.floor(a/(n||1))+1,pageSize:n,hasMore:a+n<i.length}}async batchSave(e,t,s){this.emit("batch:started","save",t.length);let r=0;const i=s?.batchSize||100;for(let a=0;a<t.length;a+=i){const n=t.slice(a,a+i);for(const i of n)await this.save(e,i.key,i.data,i.ttl),r++,s?.onProgress&&s.onProgress(r,t.length)}this.emit("batch:completed","save",r,0)}async batchLoad(e,t){const s=new Map;for(const r of t){const t=await this.load(e,r);null!==t&&s.set(r,t)}return s}async batchDelete(e,t){let s=0;for(const r of t)await this.delete(e,r)&&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,r]of this.storage.entries())r.expiry&&e>r.expiry&&(this.storage.delete(s),t++);return this.logger.info(`清理过期数据: ${t} 项`),t}async getStats(){const e={};for(const t of Object.values(exports.DataType))e[t]=0;for(const t of this.storage.keys()){const[s]=t.split(":");s in e&&e[s]++}return{totalItems:this.storage.size,itemsByType:e,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,r]of Object.entries(t))if(e[s]!==r)return!1;return!0}applySorting(e,t){return e.sort((e,s)=>{for(const r of t){const t=e.data[r.field],i=s.data[r.field];let a=0;if(t<i?a=-1:t>i&&(a=1),0!==a)return"desc"===r.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 V extends k{constructor(e){super(),this.logger=m.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,r){const i=this.buildFilePath(e,t),a={data:s,expiry:r?Date.now()+1e3*r:void 0,savedAt:Date.now()};await this.fs.writeFile(i,JSON.stringify(a,null,2)),this.emit("data:saved",e,t,s),this.logger.debug(`保存文件: ${i}`)}async load(e,t){const s=this.buildFilePath(e,t);try{const r=await this.fs.readFile(s,"utf8"),i=JSON.parse(r);return i.expiry&&Date.now()>i.expiry?(await this.fs.unlink(s),null):(this.emit("data:loaded",e,t,i.data),i.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),r=[];try{const t=await this.fs.readdir(s);for(const s of t)if(s.endsWith(".json")){const t=s.replace(".json",""),i=await this.load(e,t);null!==i&&r.push({key:t,data:i})}}catch(e){if("ENOENT"!==e.code)throw e}let i=r;t.filters&&(i=r.filter(e=>this.matchesFilters(e.data,t.filters))),t.sort&&t.sort.length>0&&(i=this.applySorting(i,t.sort));const a=t.offset||0,n=t.limit||i.length;return{data:i.slice(a,a+n).map(e=>e.data),total:i.length,page:Math.floor(a/(n||1))+1,pageSize:n,hasMore:a+n<i.length}}async batchSave(e,t,s){this.emit("batch:started","save",t.length);let r=0;const i=s?.batchSize||100;for(let a=0;a<t.length;a+=i){const n=t.slice(a,a+i);await Promise.all(n.map(async i=>{await this.save(e,i.key,i.data,i.ttl),r++,s?.onProgress&&s.onProgress(r,t.length)}))}this.emit("batch:completed","save",r,0)}async batchLoad(e,t){const s=new Map;return await Promise.all(t.map(async t=>{const r=await this.load(e,t);null!==r&&s.set(t,r)})),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 e=0;for(const t of Object.values(exports.DataType)){const s=this.path.join(this.basePath,t);try{const t=await this.fs.readdir(s);for(const r of t)if(r.endsWith(".json")){const t=this.path.join(s,r),i=await this.fs.readFile(t,"utf8"),a=JSON.parse(i);a.expiry&&Date.now()>a.expiry&&(await this.fs.unlink(t),e++)}}catch(e){"ENOENT"!==e.code&&this.logger.warn(`清理目录失败 ${s}:`,e)}}return this.logger.info(`清理过期文件: ${e} 个`),e}async getStats(){const e={};let t=0,s=0;for(const r of Object.values(exports.DataType)){e[r]=0;const i=this.path.join(this.basePath,r);try{const a=await this.fs.readdir(i);for(const n of a)if(n.endsWith(".json")){e[r]++,t++;const a=this.path.join(i,n);s+=(await this.fs.stat(a)).size}}catch(e){"ENOENT"!==e.code&&this.logger.warn(`获取统计信息失败 ${i}:`,e)}}return{totalItems:t,itemsByType:e,storageSize:s,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 e of Object.values(exports.DataType)){const t=this.path.join(this.basePath,e);await this.fs.mkdir(t,{recursive:!0})}}matchesFilters(e,t){for(const[s,r]of Object.entries(t))if(e[s]!==r)return!1;return!0}applySorting(e,t){return e.sort((e,s)=>{for(const r of t){const t=e.data[r.field],i=s.data[r.field];let a=0;if(t<i?a=-1:t>i&&(a=1),0!==a)return"desc"===r.order?-a:a}return 0})}generateTransactionId(){return`tx_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}class B{static create(e){switch(e.type){case"memory":return new U;case"file":const t=e.options?.basePath||"./data";return new V(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}`)}}}B.logger=m.createLogger("DataPersistenceFactory"),exports.AdvancedSerializer=class extends k{constructor(){super(),this.logger=m.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 r={typeName:e,typeId:this.nextTypeId++,version:t.getVersion(),serializer:t,dependencies:s};this.typeRegistry.set(e,r),this.emit("type:registered",r),this.logger.info(`注册类型序列化器: ${e} (ID: ${r.typeId})`)}serialize(e,t={}){const s=Date.now(),r={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",r);try{const t=this.serializeObject(e,r,""),i=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:i,objectCount:r.referenceMap.size,typeCount:new Set(Array.from(r.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,r),{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(),r={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",r);try{const t=this.deserializeObject(e,r),i={success:!0,data:t,metadata:{deserializationTime:Date.now()-s,objectCount:r.referenceMap.size,referencesResolved:r.referenceMap.size,circularRefsRepaired:0}};return this.emit("deserialization:complete",i),i}catch(e){const t=e instanceof Error?e.message:"Unknown deserialization error";return this.emit("deserialization:error",t,r),{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,r=0){if(r>=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 r=t.referenceMap.get(e);return{__type:"CircularReference",__version:t.version,data:{refId:r}}}if(null===e||"object"!=typeof e)return{__type:typeof e,__version:t.version,data:{value:e}};t.circularRefs.add(e);try{const i=e.constructor.name,a=this.generateId();t.referenceMap.set(e,a);const n=this.getCustomSerializer(i,t);if(n){const s=n.serialize(e,t);return s.__id=a,s}return this.serializeDefaultObject(e,t,s,r+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 r=s.deserialize(e,t);return e.__id&&t.referenceMap.set(e.__id,r),r}return this.deserializeDefaultObject(e,t)}serializeDefaultObject(e,t,s,r,i){const a={},n=e.constructor.name;for(const i in e){if(!e.hasOwnProperty(i))continue;if(t.options.excludeFields?.includes(i))continue;if(t.options.includeOnlyFields&&!t.options.includeOnlyFields.includes(i))continue;const n=e[i],o=s?`${s}.${i}`:i;try{a[i]=this.serializeObject(n,t,o,r)}catch(e){this.logger.warn(`序列化字段失败: ${o}`,e);continue}}return{__type:n,__version:t.version,__id:i,data:a}}deserializeDefaultObject(e,t){const s={};e.__id&&t.referenceMap.set(e.__id,s);for(const r in e.data)try{s[r]=this.deserializeObject(e.data[r],t)}catch(e){this.logger.warn(`反序列化字段失败: ${r}`,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],r)=>[this.serializeObject(e,t,`[${r}].key`,0),this.serializeObject(s,t,`[${r}].value`,0)])}}),deserialize:(e,t)=>{const s=new Map;for(const[r,i]of e.data.entries){const e=this.deserializeObject(r,t),a=this.deserializeObject(i,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)}`}},exports.BandwidthMonitor=class extends k{constructor(e={}){super(),this.logger=m.createLogger("BandwidthMonitor"),this.samples=[],this.currentWarningLevel=exports.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,...e},this.limits={uploadLimit:1048576,downloadLimit:1048576,enabled:!1},this.startMonitoring()}recordActivity(e,t,s=0,r=0,i=0){this.cumulativeBytesIn+=e,this.cumulativeBytesOut+=t,this.cumulativePacketsIn+=s,this.cumulativePacketsOut+=r,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,r=this.cumulativeBytesIn/t,i=(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=r,this.stats.currentPacketRate=i,this.stats.peakUpload=Math.max(this.stats.peakUpload,s),this.stats.peakDownload=Math.max(this.stats.peakDownload,r),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 r=1;r<this.samples.length;r++){const i=this.samples[r-1],a=this.samples[r],n=(a.timestamp-i.timestamp)/1e3;n>0&&(e+=(a.bytesOut-i.bytesOut)/n,t+=(a.bytesIn-i.bytesIn)/n,s+=a.latency)}const r=this.samples.length-1;r>0&&(this.stats.averageUpload=e/r,this.stats.averageDownload=t/r,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 e=exports.BandwidthWarningLevel.Normal;this.stats.utilization>=this.config.criticalThreshold?e=exports.BandwidthWarningLevel.Critical:this.stats.utilization>=this.config.warningThreshold&&(e=exports.BandwidthWarningLevel.Warning),e!==this.currentWarningLevel&&(this.currentWarningLevel=e,this.emit("warningLevelChanged",e,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)}},exports.ClientRpc=function(e={}){return function(t,s,r){const i=t.constructor.name,a=String(s),n=Reflect.getMetadata("design:paramtypes",t,s)||[],o=Reflect.getMetadata("design:returntype",t,s),c={methodName:a,className:i,isServerRpc:!1,options:{reliable:!1,priority:3,target:exports.RpcTarget.All,timeout:1e4,requireAuth:!1,rateLimit:30,...e},paramTypes:n.map(e=>e?.constructor?.name||"unknown"),returnType:o?.name||"unknown"};Reflect.defineMetadata(O,c,t,s);const l=Reflect.getMetadata(N,t.constructor)||[];l.push(a),Reflect.defineMetadata(N,l,t.constructor);const h=r.value;return r.value=async function(...e){return h.apply(this,e)},r}},exports.DEFAULT_SYNCVAR_OPTIONS=D,exports.DataPersistenceFactory=B,exports.DeltaSync=class{constructor(e={}){this.logger=m.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),r={version:s,timestamp:Date.now(),data:this.deepClone(t),checksum:this.calculateChecksum(t)};return this.storeVersion(e,r),s}calculateDelta(e,t,s){if(!this.config.enabled)return null;const r=this.versionHistory.get(e);if(!r||0===r.size)return this.recordBaseline(e,t),null;let i;if(void 0!==s){const t=r.get(s);if(t)i=t;else{this.logger.warn(`未找到版本 ${s},使用最新版本`);const t=this.getLatestVersion(e);if(!t)return this.logger.error(`实例 ${e} 没有任何版本历史`),null;i=t}}else{const t=this.getLatestVersion(e);if(!t)return this.logger.error(`实例 ${e} 没有任何版本历史`),null;i=t}const a=this.getNextVersion(e),n=this.computeChanges(i.data,t),o=this.computeDeletions(i.data,t);if(0===Object.keys(n).length&&0===o.length)return null;const c={baseVersion:i.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 r=s.get(t.baseVersion);if(!r)return this.logger.error(`未找到基线版本 ${t.baseVersion}`),null;const i=this.deepClone(r.data);for(const[e,s]of Object.entries(t.changes))this.setNestedProperty(i,e,s);for(const e of t.deletions)this.deleteNestedProperty(i,e);const a={version:t.targetVersion,timestamp:t.metadata.timestamp,data:this.deepClone(i),checksum:this.calculateChecksum(i)};return this.storeVersion(e,a),i}mergeOperations(e,t){if(!this.config.enableSmartMerging||t.length<=1)return t;const s=new Map;for(const e of t){const t=s.get(e.path);if(t){const r=this.mergeTwoOperations(t,e);s.set(e.path,r),this.stats.mergedOperations++}else s.set(e.path,e)}return Array.from(s.values()).filter(e=>e.type!==exports.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 r=this.mergeTimers.get(e);r&&clearTimeout(r);const i=setTimeout(()=>{this.flushPendingOperations(e)},this.config.mergeWindow);this.mergeTimers.set(e,i)}compressDelta(e){if(e.metadata.size<this.config.compressionThreshold)return e;const t=this.compressObject(e.changes),s=e.deletions,r=e.metadata.size,i=this.estimateSize(t)+this.estimateSize(s);return{...e,changes:t,deletions:s,metadata:{...e.metadata,size:i,compressionRatio:i/r}}}cleanup(){const e=Date.now();for(const[t,s]of this.versionHistory){const r=[];for(const[t,i]of s)e-i.timestamp>this.config.versionTimeout&&r.push(t);const i=Array.from(s.keys()).sort((e,t)=>t-e).slice(0,this.config.maxHistoryVersions);for(const e of r)i.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[r,i]of Object.entries(t)){const t=e[r];this.deepEqual(t,i)||(s[r]=i)}return s}computeDeletions(e,t){const s=[];for(const r of Object.keys(e))r in t||s.push(r);return s}mergeTwoOperations(e,t){const s={type:t.type,path:t.path,oldValue:e.oldValue,newValue:t.newValue,timestamp:t.timestamp};return e.type===exports.DeltaOperationType.ADD&&t.type===exports.DeltaOperationType.DELETE?{type:exports.DeltaOperationType.NOOP,path:t.path,oldValue:void 0,newValue:void 0,timestamp:t.timestamp}:(e.type===exports.DeltaOperationType.DELETE&&t.type===exports.DeltaOperationType.ADD&&(s.type=exports.DeltaOperationType.MODIFY,s.oldValue=e.oldValue),e.type===exports.DeltaOperationType.MODIFY&&t.type===exports.DeltaOperationType.DELETE&&(s.type=exports.DeltaOper