topazcube 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/server.cjs +16 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -1
- package/dist/server.d.ts +6 -1
- package/dist/server.js +16 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +1 -1
- package/src/server.ts +18 -1
package/dist/client.cjs
CHANGED
|
@@ -520,7 +520,7 @@ var TopazCubeClient = class {
|
|
|
520
520
|
try {
|
|
521
521
|
(0, import_fast_json_patch.applyOperation)(this.documents[name], dop);
|
|
522
522
|
} catch (e) {
|
|
523
|
-
this.
|
|
523
|
+
this.warn("applyOperation failed for", name, "with op", dop, e);
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
this.isPatched = false;
|
package/dist/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/utils.ts","../src/compress-browser.ts"],"sourcesContent":["import { applyOperation } from 'fast-json-patch'\nimport {\n reactive,\n opmsg,\n msgop,\n decode_uint32,\n decode_fp412,\n decode_fp168,\n decode_fp1616,\n deepGet,\n encode,\n decode,\n} from './utils'\nimport { compress, decompress } from './compress-browser'\nimport { glMatrix, vec3, quat } from 'gl-matrix'\n\nconst MAX_PACKAGE_SIZE = 65400; // Slightly below the 65535 limit to allow for overhead\n\ninterface Stats {\n send: number;\n rec: number;\n recRTC: number;\n sendBps: number;\n recBps: number;\n recRTCBps: number;\n ping: number;\n stdiff: number; // server time difference\n}\n\ninterface ConstructorParams {\n url: string; // server url\n autoReconnect?: boolean; // auto reconnect on disconnect\n allowSync?: boolean; // allow sync on connect\n allowWebRTC?: boolean;\n DEBUG?: boolean;\n}\n\ninterface Message {\n c: string;\n [key: string]: any;\n}\n\ninterface Document {\n entities?: { [key: string]: any };\n origin?: vec3;\n [key: string]: any;\n}\n\ninterface Entity {\n position?: vec3;\n rotation?: quat;\n _lpos1?: vec3;\n _lpos2?: vec3;\n _lpostime1?: number | undefined;\n _lpostime2?: number | undefined;\n _lrot1?: quat;\n _lrot2?: quat;\n _lrottime1?: number | undefined;\n _lrottime2?: number | undefined;\n _lsca1?: vec3;\n _lsca2?: vec3;\n _lscatime1?: number | undefined;\n _lscatime2?: number | undefined;\n sca?: vec3;\n [key: string]: any;\n}\n// WebRTC type declarations for environments that don't have them built-in\ndeclare global {\n interface RTCPeerConnection {\n new(configuration?: RTCConfiguration): RTCPeerConnection;\n createOffer(options?: RTCOfferOptions): Promise<RTCSessionDescriptionInit>;\n createAnswer(options?: RTCAnswerOptions): Promise<RTCSessionDescriptionInit>;\n setLocalDescription(description?: RTCSessionDescriptionInit): Promise<void>;\n setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;\n addIceCandidate(candidate?: RTCIceCandidateInit): Promise<void>;\n createDataChannel(label: string, dataChannelDict?: RTCDataChannelInit): RTCDataChannel;\n close(): void;\n readonly connectionState: RTCPeerConnectionState;\n readonly iceConnectionState: RTCIceConnectionState;\n readonly iceGatheringState: RTCIceGatheringState;\n readonly localDescription: RTCSessionDescription | null;\n readonly remoteDescription: RTCSessionDescription | null;\n onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;\n ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;\n dataChannel?: RTCDataChannel;\n }\n\n interface RTCDataChannel {\n readonly label: string;\n readonly readyState: RTCDataChannelState;\n send(data: string | Blob | ArrayBuffer | ArrayBufferView): void;\n close(): void;\n onopen: ((this: RTCDataChannel, ev: Event) => any) | null;\n onclose: ((this: RTCDataChannel, ev: Event) => any) | null;\n onerror: ((this: RTCDataChannel, ev: Event) => any) | null;\n onmessage: ((this: RTCDataChannel, ev: MessageEvent) => any) | null;\n }\n\n interface RTCSessionDescription {\n readonly type: RTCSdpType;\n readonly sdp: string;\n }\n\n interface RTCIceCandidate {\n new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate;\n }\n\n interface RTCPeerConnectionIceEvent extends Event {\n readonly candidate: RTCIceCandidate | null;\n }\n\n interface RTCDataChannelEvent extends Event {\n readonly channel: RTCDataChannel;\n }\n\n type RTCPeerConnectionState = 'closed' | 'connected' | 'connecting' | 'disconnected' | 'failed' | 'new';\n type RTCIceConnectionState = 'checking' | 'closed' | 'completed' | 'connected' | 'disconnected' | 'failed' | 'new';\n type RTCIceGatheringState = 'complete' | 'gathering' | 'new';\n type RTCDataChannelState = 'closed' | 'closing' | 'connecting' | 'open';\n type RTCSdpType = 'answer' | 'offer' | 'pranswer' | 'rollback';\n\n interface RTCConfiguration {\n iceServers?: RTCIceServer[];\n iceCandidatePoolSize?: number;\n }\n\n interface RTCIceServer {\n urls: string | string[];\n username?: string;\n credential?: string;\n }\n\n interface RTCOfferOptions {\n offerToReceiveAudio?: boolean;\n offerToReceiveVideo?: boolean;\n iceRestart?: boolean;\n }\n\n interface RTCAnswerOptions {\n // Currently no standard options for answers\n }\n\n interface RTCSessionDescriptionInit {\n type: RTCSdpType;\n sdp?: string;\n }\n\n interface RTCIceCandidateInit {\n candidate?: string;\n sdpMLineIndex?: number | null;\n sdpMid?: string | null;\n usernameFragment?: string | null;\n }\n\n interface RTCDataChannelInit {\n ordered?: boolean;\n maxPacketLifeTime?: number;\n maxRetransmits?: number;\n protocol?: string;\n negotiated?: boolean;\n id?: number;\n }\n\n const RTCPeerConnection: {\n prototype: RTCPeerConnection;\n new(configuration?: RTCConfiguration): RTCPeerConnection;\n };\n\n const RTCSessionDescription: {\n prototype: RTCSessionDescription;\n new(descriptionInitDict: RTCSessionDescriptionInit): RTCSessionDescription;\n };\n\n const RTCIceCandidate: {\n prototype: RTCIceCandidate;\n new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate;\n };\n}\n\nexport default class TopazCubeClient {\n DEBUG = false\n CYCLE = 200 // update/patch rate in ms\n url = ''\n documents: { [key: string]: Document } = {}\n autoReconnect = true\n allowSync = true\n allowWebRTC = false\n isConnected = false\n isConnecting = false\n isPatched = false\n stats: Stats = {\n send: 0,\n rec: 0,\n recRTC: 0,\n\n sendBps: 0,\n recBps: 0,\n recRTCBps: 0,\n\n ping: 0,\n stdiff: 0, // server time difference\n }\n lastFullState = 0\n lastPatch = 0\n _chunks: { [key: string]: any } = {}\n le = true // Server is little endian\n _documentChanges: { [key: string]: any[] } = {}\n\n ID = 0\n socket: WebSocket | null = null\n _peerConnection: RTCPeerConnection | null = null\n _candidates: RTCIceCandidate[] = []\n _remoteCandidates: RTCIceCandidateInit[] = []\n _offerSent: boolean = false\n _dataChannel: RTCDataChannel | null = null // our data channel\n _serverDataChannel: RTCDataChannel | null = null // server data channel\n _webRTCConnected: boolean = false\n\n isInterpolated = false\n _lastInterpolate = Date.now()\n _lastUpdateId: { [key: string]: number } = {}\n _dpos: vec3 = [0, 0, 0]\n _drot: quat = [0, 0, 0, 1]\n _sca: vec3 = [1, 1, 1]\n _notifyChanges = true\n _siv: NodeJS.Timeout | null = null\n _loopiv: NodeJS.Timeout | null = null\n _updateiv: NodeJS.Timeout | null = null\n _pingiv: NodeJS.Timeout | null = null\n\n\n constructor({\n url, // server url\n autoReconnect = true, // auto reconnect on disconnect\n allowSync = true, // allow sync on connect\n allowWebRTC = false,\n DEBUG = false\n }: ConstructorParams) {\n this.url = url\n this.autoReconnect = autoReconnect\n this.allowSync = allowSync\n this.allowWebRTC = allowWebRTC\n this.socket = null\n this.DEBUG = DEBUG\n this._startLoop()\n this.log('Client initialized')\n }\n\n log(...args: any[]) {\n if (this.DEBUG) {\n console.log(...args);\n }\n }\n\n warn(...args: any[]) {\n if (this.DEBUG) {\n console.warn(...args);\n }\n }\n\n error(...args: any[]) {\n console.error(...args);\n }\n\n /*= UPDATE ===================================================================*/\n\n _startLoop() {\n if (this._loopiv) {\n clearInterval(this._loopiv)\n }\n this._loopiv = setInterval(() => {\n this._loop()\n }, this.CYCLE)\n this._siv = setInterval(() => {\n this._updateStats()\n }, 1000)\n this._pingiv = setInterval(() => {\n this._ping()\n }, 10000)\n }\n _loop() {\n if (!this.isConnected) {\n return\n }\n this._sendPatches()\n }\n\n _updateStats() {\n this.stats.recBps = this.stats.rec\n this.stats.rec = 0\n this.stats.recRTCBps = this.stats.recRTC\n this.stats.recRTC = 0\n this.stats.sendBps = this.stats.send\n this.stats.send = 0\n }\n\n _clear() {\n this.stats.sendBps = 0\n this.stats.recBps = 0\n this.stats.recRTC = 0\n this.stats.recRTCBps = 0\n this.stats.send = 0\n this.stats.rec = 0\n\n this.ID = 0\n this.documents = {}\n this._documentChanges = {}\n this._lastUpdateId = {}\n this.lastFullState = 0\n this.lastPatch = 0\n this._lastInterpolate = 0\n this.isPatched = false\n this.le = true\n }\n\n /*= INTERPOLATION ============================================================*/\n\n // to be called in display rate (like 60fps) to interpolate .position, .rotation and .scale\n interpolate() {\n let now = Date.now()\n let dt = now - this._lastInterpolate\n this._lastInterpolate = now\n if (dt <= 0 || dt > 200) { return }\n this.isInterpolated = true\n for (let name in this.documents) {\n let doc = this.documents[name]\n let entities = doc?.entities\n if (!entities) { continue }\n for (let id in entities) {\n let e: Entity = entities[id]\n if (e._lpostime1 && e._lpostime2) {\n let t1 = e._lpostime1\n let t2 = e._lpostime2\n const interval = t2 - t1;\n const elapsed = now - t1;\n e.pelapsed = elapsed\n /*if (elapsed > 5000) {\n } else */if (elapsed > 1000) {\n vec3.copy(e.position!, e._lpos2!)\n e._changed_position = now\n } else {\n const alpha = Math.max(0, elapsed / interval)\n vec3.lerp(this._dpos, e._lpos1!, e._lpos2!, alpha)\n vec3.lerp(e.position!, e.position!, this._dpos, 0.07)\n e._changed_position = now\n }\n }\n if (e._lrottime1 && e._lrottime2) {\n let t1 = e._lrottime1\n let t2 = e._lrottime2\n const interval = t2 - t1;\n const elapsed = now - t1;\n e.relapsed = elapsed\n /*if (elapsed > 5000) {\n } else */if (elapsed > 1000) {\n quat.copy(e.rotation!, e._lrot2!)\n e._changed_rotation = now\n } else {\n const alpha = Math.max(0, elapsed / interval)\n quat.slerp(this._drot, e._lrot1!, e._lrot2!, alpha)\n quat.slerp(e.rotation!, e.rotation!, this._drot, 0.07)\n e._changed_rotation = now\n }\n }\n\n }\n }\n this.isInterpolated = false\n }\n\n /*= CONNECTION ===============================================================*/\n\n subscribe(name: string) {\n this.documents[name] = {}\n this.send({ c: 'sub', n: name })\n }\n\n unsubscribe(name: string) {\n this.send({ c: 'unsub', n: name })\n delete this.documents[name]\n }\n\n connect() {\n if (this.isConnecting) {\n return\n }\n this.isConnecting = true\n this._clear()\n this.log('connecting...')\n\n this.socket = new WebSocket(this.url)\n\n // message received\n this.socket.onmessage = async (event: MessageEvent) => {\n let buffer = await event.data.arrayBuffer()\n this.stats.rec += buffer.byteLength\n let dec = await decompress(buffer)\n let decu = new Uint8Array(dec)\n let message = decode(decu)\n this._onMessage(message)\n }\n\n // connection closed\n this.socket.onclose = (_event: any) => {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n this.socket = null\n this.onDisconnect()\n if (this.allowWebRTC) {\n this._destroyWebRTC()\n }\n if (this.autoReconnect) {\n setTimeout(\n () => {\n this._reconnect()\n },\n 500 + Math.random() * 500\n )\n }\n }\n\n this.socket.onerror = (_event: Event) => {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n this.socket = null\n this.onDisconnect()\n if (this.allowWebRTC) {\n this._destroyWebRTC()\n }\n\n if (this.autoReconnect) {\n setTimeout(\n () => {\n this._reconnect()\n },\n 500 + Math.random() * 500\n )\n }\n }\n\n this.socket.onopen = async (_event: Event) => {\n this._clear()\n this.isConnecting = false\n this.isConnected = true\n this.lastFullState = 0\n this._ping()\n this.onConnect()\n if (this.allowWebRTC) {\n await this._initializeWebRTC()\n }\n }\n }\n\n disconnect() {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n if (this.socket) {\n this.socket.close()\n }\n this.socket = null\n }\n\n destroy() {\n this._clear()\n this.autoReconnect = false\n this.disconnect()\n this.socket = null\n if (this._siv) clearInterval(this._siv)\n if (this._loopiv) clearInterval(this._loopiv)\n }\n\n onConnect() {}\n\n onDisconnect() {}\n\n _reconnect() {\n if (!this.isConnected) {\n if (!this.isConnecting) {\n this.connect()\n }\n }\n }\n\n _ping() {\n if (this.isConnected) {\n this.send({ c: 'ping', ct: Date.now() })\n }\n }\n\n /*= MESSAGES =================================================================*/\n\n onChange(_name: string, _doc: Document | undefined, patch: any | undefined) {}\n\n onMessage(_message: Message) {}\n\n send(operation: any) {\n try {\n let enc = encode(operation)\n this.stats.send += enc.byteLength\n if (this.socket) {\n this.socket.send(enc)\n }\n } catch (e) {\n this.error('send failed', e)\n }\n }\n\n get document(): Document | undefined {\n let names:string = ''+Object.keys(this.documents)\n return this.documents[''+names[0]]\n }\n\n async _onMessage(message: Message) {\n let time = Date.now()\n if (message.c == 'full') {\n //this.log('full:', message)\n let name:string = ''+message.n\n let doc = message.doc\n this.documents[name] = doc\n this._decodeFastChanges(message)\n this.isPatched = false\n if (this.allowSync) {\n this.documents[name] = reactive(\n name,\n this.documents[name],\n this._onDocumentChange.bind(this)\n )\n }\n this.isPatched = false\n this.lastFullState = message.t\n this.le = message.le\n if (this._notifyChanges) {\n this.onChange(name, this.documents[name], null)\n }\n } else if (message.c == 'patch') {\n // patch\n this.lastPatch = message.t\n let name = message.n\n if (!this.documents[name]) {\n this.warn('Patch for unknown document', name)\n return\n }\n if (message.doc) {\n this.isPatched = true\n for (let op of message.doc) {\n let dop = msgop(op)\n try {\n applyOperation(this.documents[name], dop)\n } catch (e) {\n this.error('applyOperation failed for', name, 'with op', dop, e)\n }\n }\n this.isPatched = false\n }\n if (this._notifyChanges) {\n this.onChange(name, this.documents[name], message.doc)\n }\n } else if (message.c == 'chunk') {\n //this.log('chunk', message)\n this._chunks[message.mid+'-'+message.seq] = message\n if (message.last) {\n let cfound = 0\n let ts = message.ts\n let cdata = new Uint8Array(ts)\n for (const cid in this._chunks) {\n let chunk = this._chunks[cid]\n if (chunk.mid == message.mid) {\n let offset = chunk.ofs\n let _csize = chunk.chs\n cdata.set(new Uint8Array(chunk.data), offset);\n cfound++\n delete this._chunks[cid]\n }\n }\n //this.log('found chunks ', cfound, 'of', message.seq + 1)\n if (cfound == message.seq + 1) {\n try {\n let cdec = await decompress(cdata)\n let cdecu = new Uint8Array(cdec)\n let nmessage = decode(cdecu)\n //this.log('decoded message', nmessage)\n this._onMessage(nmessage)\n } catch (error) {\n this.error('Error decoding chunks:', error)\n }\n } else {\n this.warn('missing chunks', cfound, 'of', message.seq + 1)\n }\n }\n } else if (message.c == 'fpatch') {\n time = Date.now()\n let name = message.n\n //this.log('fpatch', message)\n let doPatch = true\n if (!this._lastUpdateId[name]) {\n this._lastUpdateId[name] = message.u\n } else {\n if (this._lastUpdateId[name] < message.u) {\n let lp = message.u - this._lastUpdateId[name] - 1\n if (lp > 0) {\n this.warn('Lost ' + lp + ' updates')\n }\n this._lastUpdateId[name] = message.u\n } else if (this._lastUpdateId[name] > message.u) {\n // Handle the case where the server's update ID is older than the client's\n // This could be due to a network issue or a clock skew\n this.warn(`Received outdated update ID for document ${name}: ${message.u} < ${this._lastUpdateId[name]}`)\n doPatch = false\n }\n }\n if (doPatch) {\n this._decodeFastChanges(message)\n }\n } else if (message.c == 'pong') {\n this.ID = message.ID\n time = Date.now()\n let lastct = message.ct\n let ping = time - lastct\n let stime = message.t\n this.send({ c: 'peng', ct: Date.now(), st: stime })\n this.stats.stdiff = stime + ping / 2 - time\n this.stats.ping = ping\n this.log('ping', ping, 'ms', 'stdiff', this.stats.stdiff, 'ms')\n } else if (message.c == 'rtc-offer') {\n this.log(\"RTC: offer received:\", message);\n // You might need to handle this if the server sends offers\n } else if (message.c == 'rtc-answer') {\n this.log(\"RTC: answer received:\", message);\n try {\n const sessionDesc = new RTCSessionDescription({\n type: message.type,\n sdp: message.sdp,\n })\n if (this._peerConnection) {\n await this._peerConnection.setRemoteDescription(sessionDesc)\n }\n this.log(\"RTC: Remote description set successfully\");\n\n // Log the current state after setting remote description\n //\n //this.log(\"RTC: Current connection state:\", this._peerConnection.connectionState);\n //this.log(\"RTC: Current ICE connection state:\", this._peerConnection.iceConnectionState);\n for (let candidate of this._remoteCandidates) {\n try {\n await this._peerConnection?.addIceCandidate(candidate);\n this.log(\"RTC: Added remote ICE candidate:\", candidate);\n } catch (error) {\n this.error(\"RTC: Error adding remote ICE candidate:\", error);\n }\n }\n } catch (error) {\n this.error('RTC: Error setting remote description:', error)\n }\n } else if (message.c == 'rtc-candidate') {\n this.log(\"RTC: candidate received\", message);\n if (this._peerConnection && message.candidate) {\n this._remoteCandidates.push(message.candidate);\n }\n } else {\n this.onMessage(message)\n }\n }\n\n _onDocumentChange(name: string, op: any, target: any, path: string, value: any) {\n if (this.DEBUG) {\n this.log('Document change:', name, op, target, path, value)\n }\n if (this.isPatched || !this.allowSync) {\n return\n }\n if (path.indexOf('/_') >= 0) {\n return\n }\n if (!this._documentChanges[name]) {\n this._documentChanges[name] = []\n }\n this._documentChanges[name].push(opmsg(op, target, path, value))\n }\n\n _sendPatches() {\n for (let name in this._documentChanges) {\n let dc = this._documentChanges[name]\n if (!dc || dc.length == 0) {\n continue\n }\n let record: any = {\n n: name,\n c: 'sync',\n ct: Date.now(),\n p: null\n }\n\n if (dc.length > 0) {\n record.p = dc\n }\n this.send(record)\n dc.length = 0\n if (this._notifyChanges) {\n this.onChange(name, this.documents[''+name], record.p)\n }\n }\n }\n\n _decodeFastChanges(message: Message) {\n let time = Date.now()\n let name = message.n\n let fdata = message.fdata\n if (!fdata) {\n return\n }\n let doc = this.documents[name]\n if (!doc) {\n return\n }\n let entities = doc.entities\n if (!entities) {\n return\n }\n let origin = this.documents[''+name]?.origin\n if (!origin) {\n origin = [0, 0, 0]\n }\n for (let key in fdata) {\n let changes = fdata[key]\n if (changes.dict) {\n let pdata = changes.pdata\n let dict = changes.dict\n // Reverse the dictionary for lookup (value to key)\n let rdict: { [key: string]: string } = {};\n for (let key in dict) {\n rdict[dict[key]] = key;\n }\n let offset = 0\n\n while (offset < pdata.byteLength) {\n let id = ''+decode_uint32(pdata, offset)\n offset += 4\n let did = ''+decode_uint32(pdata, offset)\n offset += 4\n let e: Entity = entities[id]\n if (!e) {\n //this.log('Entity not found:', id)\n continue\n }\n let value = rdict[did]\n e[key] = value\n //this.log('FCHANGE', key, id, did, value, rdict)\n e['_changed_'+key] = time\n }\n } else {\n let pdata = changes.pdata\n let offset = 0\n while (offset < pdata.byteLength) {\n let id = ''+decode_uint32(pdata, offset)\n let e: Entity = entities[id]\n if (!e) {\n if (key == 'position') {\n offset += 13\n } else if (key == 'rotation') {\n offset += 8\n } else if (key == 'scale') {\n offset += 16\n }\n continue\n }\n offset += 4\n\n if (key == 'position') {\n if (!e._lpos2) {\n e._lpos1 = [0, 0, 0]\n e._lpos2 = [0, 0, 0]\n } else {\n e._lpos1![0] = e._lpos2[0]\n e._lpos1![1] = e._lpos2[1]\n e._lpos1![2] = e._lpos2[2]\n e._lpostime1 = e._lpostime2\n }\n e._lpostime2 = time\n e._lpos2[0] = origin[0] + decode_fp168(pdata, offset)\n offset += 3\n e._lpos2[1] = origin[1] + decode_fp168(pdata, offset)\n offset += 3\n e._lpos2[2] = origin[2] + decode_fp168(pdata, offset)\n offset += 3\n if (!e.position) {\n e.position = [\n e._lpos2[0],\n e._lpos2[1],\n e._lpos2[2],\n ]\n }\n } else if (key == 'rotation') {\n if (!e._lrot2) {\n e._lrot1 = [0, 0, 0, 1]\n e._lrot2 = [0, 0, 0, 1]\n } else {\n e._lrot1![0] = e._lrot2[0]\n e._lrot1![1] = e._lrot2[1]\n e._lrot1![2] = e._lrot2[2]\n e._lrot1![3] = e._lrot2[3]\n e._lrottime1 = e._lrottime2\n }\n e._lrottime2 = time\n e._lrot2[0] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[1] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[2] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[3] = decode_fp412(pdata, offset)\n offset += 2\n quat.normalize(e._lrot2, e._lrot2)\n if (!e.rotation) {\n e.rotation = [\n e._lrot2[0],\n e._lrot2[1],\n e._lrot2[2],\n e._lrot2[3],\n ]\n }\n } else if (key == 'scale') {\n if (!e._lsca2) {\n e._lsca1 = [0, 0, 0]\n e._lsca2 = [0, 0, 0]\n } else {\n e._lsca1![0] = e._lsca2[0]\n e._lsca1![1] = e._lsca2[1]\n e._lsca1![2] = e._lsca2[2]\n e._lscatime1 = e._lscatime2\n }\n e._lscatime2 = time\n e._lsca2[0] = decode_fp1616(pdata, offset)\n offset += 4\n e._lsca2[1] = decode_fp1616(pdata, offset)\n offset += 4\n e._lsca2[2] = decode_fp1616(pdata, offset)\n offset += 4\n if (!e.sca) {\n e.sca = [\n e._lsca2[0],\n e._lsca2[1],\n e._lsca2[2],\n ]\n }\n }\n }\n }\n }\n }\n\n /*= WEBRTC ===================================================================*/\n\n sendRTC(message: Message) {\n if (this._dataChannel && this._dataChannel.readyState === 'open') {\n this._dataChannel.send(encode(message))\n }\n }\n\n _onRTCConnect() {\n this.log('RTC: Connected')\n this.send({ c: 'test', message: 'Hello RTC from client' })\n }\n\n _onRTCDisconnect() {\n this._webRTCConnected = false\n this.log('RTC: Disconnected')\n }\n\n async _onRTCMessage(data: ArrayBuffer) {\n this.stats.recRTC += data.byteLength\n let datau = new Uint8Array(data)\n let dec = await decompress(datau)\n let decu = new Uint8Array(dec)\n let message = decode(decu)\n this._onMessage(message)\n }\n\n async _initializeWebRTC() {\n //this.log(\"RTC: _initializeWebRTC\")\n this._peerConnection = null\n this._candidates = []\n this._remoteCandidates = []\n this._offerSent = false\n try {\n // Create RTCPeerConnection with more comprehensive STUN server list\n this._peerConnection = new RTCPeerConnection({\n iceServers: [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:stun.cloudflare.com:3478' },\n { urls: 'stun:freestun.net:3478' },\n ],\n iceCandidatePoolSize: 10,\n })\n\n //this.log(\"RTC: peerConnection created\", this._peerConnection)\n\n // Handle ICE candidates\n this._peerConnection.onicecandidate = (event: RTCPeerConnectionIceEvent) => {\n //this.log(\"RTC: onicecandidate\", event.candidate)\n if (event.candidate) {\n this._candidates.push(event.candidate)\n } else {\n this.log(\"RTC: ICE candidate gathering complete\")\n }\n }\n\n // Log connection state changes\n this._peerConnection.onconnectionstatechange = () => {\n //this.log(`RTC: Connection state changed: ${this._peerConnection.connectionState}`)\n if (this._peerConnection && this._peerConnection.connectionState === 'connected') {\n this._webRTCConnected = true\n this.log('RTC: Peer connection established!')\n } else if (\n this._peerConnection && (\n this._peerConnection.connectionState === 'failed' ||\n this._peerConnection.connectionState === 'disconnected' ||\n this._peerConnection.connectionState === 'closed')\n ) {\n this._webRTCConnected = false\n this.log('RTC: Peer connection closed or failed')\n }\n }\n\n this._peerConnection.onicegatheringstatechange = () => {\n this.log(`RTC: ICE gathering state. _candidates:`, this._candidates.length, this._peerConnection?.iceGatheringState)\n if (this._peerConnection?.iceGatheringState == 'complete' && this._offerSent) {\n for (let candidate of this._candidates) {\n this.send({\n c: 'rtc-candidate',\n type: 'ice-candidate',\n candidate: candidate,\n })\n }\n }\n }\n\n this._peerConnection.oniceconnectionstatechange = () => {\n //this.log(`RTC: ICE connection state: ${this._peerConnection.iceConnectionState}`)\n\n // This is critical - when ICE succeeds, the connection should be established\n if (\n this._peerConnection && (\n this._peerConnection.iceConnectionState === 'connected' ||\n this._peerConnection.iceConnectionState === 'completed')\n ) {\n //this.log(\"RTC: ICE connection established!\")\n }\n }\n\n // Create a data channel on our side as well (belt and suspenders approach)\n this._dataChannel = this._peerConnection.createDataChannel(\n 'clientchannel',\n {\n ordered: true,\n maxRetransmits: 1,\n }\n )\n\n this._dataChannel.onopen = () => {\n this._onRTCConnect()\n }\n\n this._dataChannel.onclose = () => {\n this._onRTCDisconnect()\n }\n\n this._dataChannel.onerror = (_error: Event) => {\n this.error('RTC: Client data channel error', _error)\n }\n\n // Handle data channels created by the server\n this._peerConnection.ondatachannel = (event: RTCDataChannelEvent) => {\n //this.log(\"RTC: Server data channel received\", event.channel.label);\n const dataChannel = event.channel\n this._serverDataChannel = dataChannel\n\n dataChannel.onopen = () => {\n //this.log(\"RTC: Server data channel open\");\n }\n\n dataChannel.onclose = () => {\n //this.log(\"RTC: Server data channel closed\");\n }\n\n dataChannel.onerror = (_error: Event) => {\n //this.error(\"RTC: Server data channel error\", error);\n }\n\n dataChannel.onmessage = (event: MessageEvent) => {\n this._onRTCMessage(event.data)\n }\n }\n\n // Create and send offer with specific constraints\n const offerOptions: RTCOfferOptions = {\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n iceRestart: true,\n }\n\n const offer = await this._peerConnection.createOffer(offerOptions)\n //this.log(\"RTC: our offer:\", offer);\n await this._peerConnection.setLocalDescription(offer)\n\n // Wait a moment to ensure the local description is set\n await new Promise((resolve) => setTimeout(resolve, 100))\n\n let ld = this._peerConnection.localDescription\n //this.log(\"RTC: our localDescription\", ld);\n\n if (ld) {\n const offerPayload = {\n c: 'rtc-offer',\n type: ld.type,\n sdp: ld.sdp,\n }\n //this.log(\"RTC: our offer payload\", offerPayload);\n this.send(offerPayload)\n this._offerSent = true\n }\n\n // Set a timeout to check connection status\n setTimeout(() => {\n if (!this._webRTCConnected && this._peerConnection) {\n /*\n this.log(\"RTC: Connection not established after timeout, current states:\");\n this.log(\"Connection state:\", this._peerConnection.connectionState);\n this.log(\"ICE connection state:\", this._peerConnection.iceConnectionState);\n this.log(\"ICE gathering state:\", this._peerConnection.iceGatheringState);\n */\n // Attempt to restart ICE if needed\n if (this._peerConnection.iceConnectionState === 'failed') {\n this.log('RTC: Attempting ICE restart')\n this._restartIce()\n }\n }\n }, 5000)\n } catch (error) {\n this.error('RTC: error:', error)\n }\n }\n\n // Add this method to restart ICE if needed\n async _restartIce() {\n try {\n const offerOptions = {\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n iceRestart: true,\n }\n\n const offer = await this._peerConnection?.createOffer(offerOptions)\n await this._peerConnection?.setLocalDescription(offer)\n\n const offerPayload = {\n c: 'rtc-offer',\n type: offer?.type,\n sdp: offer?.sdp,\n }\n //this.log(\"RTC: ICE restart offer payload\", offerPayload);\n this.send(offerPayload)\n } catch (error) {\n //this.error(\"RTC: Error during ICE restart:\", error);\n }\n }\n\n async _destroyWebRTC() {\n if (this._peerConnection) {\n if (this._peerConnection.dataChannel) {\n this._peerConnection.dataChannel.close()\n }\n this._peerConnection.close()\n this._peerConnection = null\n }\n if (this._dataChannel) {\n this._dataChannel.close()\n this._dataChannel = null\n }\n this._webRTCConnected = false\n }\n}\n","import { Packr } from 'msgpackr';\nimport { FLOAT32_OPTIONS } from 'msgpackr';\nconst { ALWAYS } = FLOAT32_OPTIONS;\n\nlet packr = new Packr({\n useFloat32: ALWAYS\n});\n\nexport function encode(obj: any): Uint8Array {\n return packr.pack(obj)\n}\n\nexport function decode(data: Uint8Array): any {\n return packr.unpack(data)\n}\n\ntype ReactiveCallback = (name: string, operation: string, target: any, path: string, value: any) => void;\n\nexport function reactive(name: string, object: any, callback: ReactiveCallback, path: string = '', excludedProperties: Record<string, boolean> | false = false): any {\n if (object === null || typeof object !== 'object') {\n //console.log('--- Type not object', typeof object)\n return object\n }\n\n function isReactive(p: string): boolean {\n let r = true\n if (p.startsWith('_')) {\n r = false\n }\n if (excludedProperties) {\n if (excludedProperties[p]) {\n r = false\n }\n }\n if (path == '/entities') {\n r = false\n }\n return r\n }\n\n for (const property in object) {\n if (isReactive(property)) {\n //console.log(`path '${path}', prop '${property}' is reactive`)\n object[property] = reactive(\n name,\n object[property],\n callback,\n path + '/' + property,\n excludedProperties\n )\n } else {\n //console.log(`--- path '${path}', property '${property}' is NOT reactive`)\n }\n }\n //console.log(`path '${path}' is reactive`)\n return new Proxy(object, {\n get(target: any, property: string | symbol, receiver: any): any { // ...arguments\n return Reflect.get(target, property, receiver)\n },\n set(target: any, property: string | symbol, value: any): boolean {\n let newvalue: any\n let pn = path + '/' + String(property)\n if (isReactive(String(property))) {\n newvalue = reactive(name, value, callback, pn, excludedProperties)\n callback(name, 'replace', target, pn, newvalue)\n } else {\n newvalue = value\n }\n return Reflect.set(target, property, newvalue)\n },\n deleteProperty(target: any, property: string | symbol): boolean {\n let pn = path + '/' + String(property)\n if (isReactive(String(property))) {\n callback(name, 'remove', target, pn, null)\n }\n delete target[property]\n return true\n },\n })\n\n}\n\nexport function deepGet(obj: any, path: string): any {\n //path = path.replace(/^\\/+/, '')\n let paths = ('' + path).split('/').filter((p) => p)\n let len = paths.length\n for (let i = 0; i < len; i++) {\n if (obj[paths[i]!] == undefined) {\n return undefined\n } else {\n obj = obj[paths[i]!]\n }\n }\n return obj\n}\n\nexport function deepSet(obj: any, path: string, value: any): void {\n //path = path.replace(/^\\/+/, '')\n let paths = ('' + path).split('/').filter((p) => p)\n let len = paths.length\n let i: number\n for (i = 0; i < len - 1; i++) {\n obj = obj[paths[i]!]\n }\n obj[paths[i]!] = value\n}\n\n// recursive clone oject, without properties that starts with _ (or __)\n\nexport function clonewo_(obj: any, excludeStart: string | Record<string, boolean> = '_'): any {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n function isExcluded(key: string): boolean {\n let e = false\n if (typeof (excludeStart) == 'string' && key.startsWith(excludeStart)) {\n e = true\n } else if (typeof(excludeStart) == 'object') {\n if (excludeStart[key] || key.startsWith('_')) {\n e = true\n }\n }\n return e\n }\n\n if (obj instanceof Map) {\n const mapClone = new Map()\n Array.from(obj.entries()).forEach(([key, value]) => {\n mapClone.set(clonewo_(key, excludeStart), clonewo_(value, excludeStart))\n })\n return mapClone\n }\n\n let clone: any\n if (Array.isArray(obj)) {\n clone = []\n for (let i = 0; i < obj.length; i++) {\n clone[i] = clonewo_(obj[i], excludeStart)\n }\n } else {\n clone = {} as Record<string, any>\n for (let key in obj) {\n if (obj.hasOwnProperty(key) && !isExcluded(key)) {\n if (typeof obj[key] === 'object') {\n clone[key] = clonewo_(obj[key], excludeStart)\n } else {\n clone[key] = obj[key]\n }\n }\n }\n }\n\n return clone\n}\n\nexport function limitPrecision(obj: any): any {\n if (Array.isArray(obj)) {\n return obj.map(limitPrecision)\n } else if (obj !== null && typeof obj === 'object') {\n const result: Record<string, any> = {}\n for (const key in obj) {\n result[key] = limitPrecision(obj[key])\n }\n return result\n } else if (typeof obj === 'number') {\n if (Number.isInteger(obj)) {\n return obj\n } else {\n // Limit to max 3 decimal digits, not fixed\n return parseFloat(obj.toFixed(3))\n }\n } else {\n return obj\n }\n}\n\nexport function msgop(op: any): any {\n let nop: any = {}\n if (!op.o) {\n nop.op = 'replace'\n } else {\n nop.op = ({\n a: 'add',\n r: 'remove',\n d: 'delete',\n t: 'test',\n } as Record<string, string>)[op.o]\n }\n nop.path = op.p\n nop.value = op.v\n return nop\n}\n\nexport function opmsg(op: string, target: any, path: string, value: any): any {\n let c: any = { p: path, v: value }\n if (op != 'replace') {\n c.o = ({\n add: 'a',\n remove: 'r',\n delete: 'd',\n test: 't',\n } as Record<string, string>)[op]\n }\n return c\n}\n\n// a function that converts an int to a hexa string\n// (8 characters long)\nexport function int2hex(int: number): string {\n return int.toString(16)\n}\n\n// a function that converts a hexa string to an int\nexport function hex2int(str: string): bigint {\n if (str.length % 2) {\n str = '0' + str\n }\n return BigInt('0x' + str)\n}\n\n// - Fixed point encoding/decoding functions\n\n// 32-bit unsigned integer encoding\nexport function encode_uint32(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(4)\n }\n let p = offset + 3\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n// 32-bit unsigned integer decoding\nexport function decode_uint32(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (\n ((byteArray[p++]! & 0x7f) << 24) |\n (byteArray[p++]! << 16) |\n (byteArray[p++]! << 8) |\n byteArray[p]!\n )\n}\n\n// 24-bit unsigned integer encoding\nexport function encode_uint24(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(3)\n }\n let p = offset + 2\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n\n// 24-bit unsigned integer decoding\nexport function decode_uint24(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (\n (byteArray[p++]! << 16) |\n (byteArray[p++]! << 8) |\n byteArray[p]!\n )\n}\n\n// 16-bit unsigned integer encoding\nexport function encode_uint16(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(2)\n }\n let p = offset + 1\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n\n// 16-bit unsigned integer decoding\nexport function decode_uint16(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (byteArray[p++]! << 8) | byteArray[p]!\n}\n\n// 24.8 bit ====================================================================\n\n// 24.8-bit fixed point encoding\nexport function encode_fp248(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint32(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 24.8-bit fixed point decoding\nexport function decode_fp248(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint32(byteArray, offset)\n return fp / divider\n}\n\n// 16.8 bit ====================================================================\n\n// 16.8-bit fixed point encoding (3 bytes)\nexport function encode_fp168(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint24(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 16.8-bit fixed point decoding (3 bytes)\nexport function decode_fp168(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint24(byteArray, offset)\n return fp / divider\n}\n\n// 16.16 bit ===================================================================\n\n// 16.16-bit fixed point encoding\nexport function encode_fp1616(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 65536)\n encode_uint32(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 16.16-bit fixed point decoding\nexport function decode_fp1616(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -65536 : 65536\n byteArray[offset]! &= 0x7f\n const fp = decode_uint32(byteArray, offset)\n return fp / divider\n}\n\n// 8.8 bit =====================================================================\n\n// 8.8-bit fixed point encoding\nexport function encode_fp88(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint16(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 8.8-bit fixed point decoding\nexport function decode_fp88(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint16(byteArray, offset)\n return fp / divider\n}\n\n// 4.12 bit ====================================================================\n\n// 4.12-bit fixed point encoding\nexport function encode_fp412(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 4096)\n encode_uint16(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 4.12-bit fixed point decoding\nexport function decode_fp412(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -4096 : 4096\n byteArray[offset]! &= 0x7f\n const fp = decode_uint16(byteArray, offset)\n return fp / divider\n}\n\n// 1.7 bit =====================================================================\n\n// 1.7-bit fixed point encoding\nexport function encode_fp17(float: number, byteArray: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 128)\n byteArray[offset] = fp\n if (float < 0) {\n byteArray[offset] |= 0x80\n }\n}\n\n// 1.7-bit fixed point decoding\nexport function decode_fp17(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -128.0 : 128.0\n byteArray[offset]! &= 0x7f\n return byteArray[offset]! / divider\n}\n","const browserFormat = 'gzip'\n\nconst MIN_COMPRESSED_BUFFER_SIZE = 256\n\nexport async function compress(buffer:Uint8Array<ArrayBufferLike>) {\n if (buffer.byteLength <= MIN_COMPRESSED_BUFFER_SIZE) return buffer\n if (typeof CompressionStream !== 'undefined') {\n const cs = new CompressionStream(browserFormat)\n const compressed = await new Response(\n new Blob([buffer]).stream().pipeThrough(cs)\n ).arrayBuffer()\n return compressed\n } else {\n throw new Error('CompressionStream not supported')\n }\n}\n\nexport async function decompress(buffer:Uint8Array<ArrayBufferLike>) {\n if (typeof DecompressionStream !== 'undefined') {\n try {\n const ds = new DecompressionStream(browserFormat)\n const decompressed = await new Response(\n new Blob([buffer]).stream().pipeThrough(ds)\n ).arrayBuffer()\n //console.log(` ${buffer.byteLength} -> ${decompressed.byteLength}`)\n return decompressed\n } catch (e) {\n //console.error('Decompression failed:', e)\n return buffer\n }\n } else {\n throw new Error('DecompressionStream not supported')\n }\n}\n"],"mappings":"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","names":["import_msgpackr","key","event"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/utils.ts","../src/compress-browser.ts"],"sourcesContent":["import { applyOperation } from 'fast-json-patch'\nimport {\n reactive,\n opmsg,\n msgop,\n decode_uint32,\n decode_fp412,\n decode_fp168,\n decode_fp1616,\n deepGet,\n encode,\n decode,\n} from './utils'\nimport { compress, decompress } from './compress-browser'\nimport { glMatrix, vec3, quat } from 'gl-matrix'\n\nconst MAX_PACKAGE_SIZE = 65400; // Slightly below the 65535 limit to allow for overhead\n\ninterface Stats {\n send: number;\n rec: number;\n recRTC: number;\n sendBps: number;\n recBps: number;\n recRTCBps: number;\n ping: number;\n stdiff: number; // server time difference\n}\n\ninterface ConstructorParams {\n url: string; // server url\n autoReconnect?: boolean; // auto reconnect on disconnect\n allowSync?: boolean; // allow sync on connect\n allowWebRTC?: boolean;\n DEBUG?: boolean;\n}\n\ninterface Message {\n c: string;\n [key: string]: any;\n}\n\ninterface Document {\n entities?: { [key: string]: any };\n origin?: vec3;\n [key: string]: any;\n}\n\ninterface Entity {\n position?: vec3;\n rotation?: quat;\n _lpos1?: vec3;\n _lpos2?: vec3;\n _lpostime1?: number | undefined;\n _lpostime2?: number | undefined;\n _lrot1?: quat;\n _lrot2?: quat;\n _lrottime1?: number | undefined;\n _lrottime2?: number | undefined;\n _lsca1?: vec3;\n _lsca2?: vec3;\n _lscatime1?: number | undefined;\n _lscatime2?: number | undefined;\n sca?: vec3;\n [key: string]: any;\n}\n// WebRTC type declarations for environments that don't have them built-in\ndeclare global {\n interface RTCPeerConnection {\n new(configuration?: RTCConfiguration): RTCPeerConnection;\n createOffer(options?: RTCOfferOptions): Promise<RTCSessionDescriptionInit>;\n createAnswer(options?: RTCAnswerOptions): Promise<RTCSessionDescriptionInit>;\n setLocalDescription(description?: RTCSessionDescriptionInit): Promise<void>;\n setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;\n addIceCandidate(candidate?: RTCIceCandidateInit): Promise<void>;\n createDataChannel(label: string, dataChannelDict?: RTCDataChannelInit): RTCDataChannel;\n close(): void;\n readonly connectionState: RTCPeerConnectionState;\n readonly iceConnectionState: RTCIceConnectionState;\n readonly iceGatheringState: RTCIceGatheringState;\n readonly localDescription: RTCSessionDescription | null;\n readonly remoteDescription: RTCSessionDescription | null;\n onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\n onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;\n ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;\n dataChannel?: RTCDataChannel;\n }\n\n interface RTCDataChannel {\n readonly label: string;\n readonly readyState: RTCDataChannelState;\n send(data: string | Blob | ArrayBuffer | ArrayBufferView): void;\n close(): void;\n onopen: ((this: RTCDataChannel, ev: Event) => any) | null;\n onclose: ((this: RTCDataChannel, ev: Event) => any) | null;\n onerror: ((this: RTCDataChannel, ev: Event) => any) | null;\n onmessage: ((this: RTCDataChannel, ev: MessageEvent) => any) | null;\n }\n\n interface RTCSessionDescription {\n readonly type: RTCSdpType;\n readonly sdp: string;\n }\n\n interface RTCIceCandidate {\n new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate;\n }\n\n interface RTCPeerConnectionIceEvent extends Event {\n readonly candidate: RTCIceCandidate | null;\n }\n\n interface RTCDataChannelEvent extends Event {\n readonly channel: RTCDataChannel;\n }\n\n type RTCPeerConnectionState = 'closed' | 'connected' | 'connecting' | 'disconnected' | 'failed' | 'new';\n type RTCIceConnectionState = 'checking' | 'closed' | 'completed' | 'connected' | 'disconnected' | 'failed' | 'new';\n type RTCIceGatheringState = 'complete' | 'gathering' | 'new';\n type RTCDataChannelState = 'closed' | 'closing' | 'connecting' | 'open';\n type RTCSdpType = 'answer' | 'offer' | 'pranswer' | 'rollback';\n\n interface RTCConfiguration {\n iceServers?: RTCIceServer[];\n iceCandidatePoolSize?: number;\n }\n\n interface RTCIceServer {\n urls: string | string[];\n username?: string;\n credential?: string;\n }\n\n interface RTCOfferOptions {\n offerToReceiveAudio?: boolean;\n offerToReceiveVideo?: boolean;\n iceRestart?: boolean;\n }\n\n interface RTCAnswerOptions {\n // Currently no standard options for answers\n }\n\n interface RTCSessionDescriptionInit {\n type: RTCSdpType;\n sdp?: string;\n }\n\n interface RTCIceCandidateInit {\n candidate?: string;\n sdpMLineIndex?: number | null;\n sdpMid?: string | null;\n usernameFragment?: string | null;\n }\n\n interface RTCDataChannelInit {\n ordered?: boolean;\n maxPacketLifeTime?: number;\n maxRetransmits?: number;\n protocol?: string;\n negotiated?: boolean;\n id?: number;\n }\n\n const RTCPeerConnection: {\n prototype: RTCPeerConnection;\n new(configuration?: RTCConfiguration): RTCPeerConnection;\n };\n\n const RTCSessionDescription: {\n prototype: RTCSessionDescription;\n new(descriptionInitDict: RTCSessionDescriptionInit): RTCSessionDescription;\n };\n\n const RTCIceCandidate: {\n prototype: RTCIceCandidate;\n new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate;\n };\n}\n\nexport default class TopazCubeClient {\n DEBUG = false\n CYCLE = 200 // update/patch rate in ms\n url = ''\n documents: { [key: string]: Document } = {}\n autoReconnect = true\n allowSync = true\n allowWebRTC = false\n isConnected = false\n isConnecting = false\n isPatched = false\n stats: Stats = {\n send: 0,\n rec: 0,\n recRTC: 0,\n\n sendBps: 0,\n recBps: 0,\n recRTCBps: 0,\n\n ping: 0,\n stdiff: 0, // server time difference\n }\n lastFullState = 0\n lastPatch = 0\n _chunks: { [key: string]: any } = {}\n le = true // Server is little endian\n _documentChanges: { [key: string]: any[] } = {}\n\n ID = 0\n socket: WebSocket | null = null\n _peerConnection: RTCPeerConnection | null = null\n _candidates: RTCIceCandidate[] = []\n _remoteCandidates: RTCIceCandidateInit[] = []\n _offerSent: boolean = false\n _dataChannel: RTCDataChannel | null = null // our data channel\n _serverDataChannel: RTCDataChannel | null = null // server data channel\n _webRTCConnected: boolean = false\n\n isInterpolated = false\n _lastInterpolate = Date.now()\n _lastUpdateId: { [key: string]: number } = {}\n _dpos: vec3 = [0, 0, 0]\n _drot: quat = [0, 0, 0, 1]\n _sca: vec3 = [1, 1, 1]\n _notifyChanges = true\n _siv: NodeJS.Timeout | null = null\n _loopiv: NodeJS.Timeout | null = null\n _updateiv: NodeJS.Timeout | null = null\n _pingiv: NodeJS.Timeout | null = null\n\n\n constructor({\n url, // server url\n autoReconnect = true, // auto reconnect on disconnect\n allowSync = true, // allow sync on connect\n allowWebRTC = false,\n DEBUG = false\n }: ConstructorParams) {\n this.url = url\n this.autoReconnect = autoReconnect\n this.allowSync = allowSync\n this.allowWebRTC = allowWebRTC\n this.socket = null\n this.DEBUG = DEBUG\n this._startLoop()\n this.log('Client initialized')\n }\n\n log(...args: any[]) {\n if (this.DEBUG) {\n console.log(...args);\n }\n }\n\n warn(...args: any[]) {\n if (this.DEBUG) {\n console.warn(...args);\n }\n }\n\n error(...args: any[]) {\n console.error(...args);\n }\n\n /*= UPDATE ===================================================================*/\n\n _startLoop() {\n if (this._loopiv) {\n clearInterval(this._loopiv)\n }\n this._loopiv = setInterval(() => {\n this._loop()\n }, this.CYCLE)\n this._siv = setInterval(() => {\n this._updateStats()\n }, 1000)\n this._pingiv = setInterval(() => {\n this._ping()\n }, 10000)\n }\n _loop() {\n if (!this.isConnected) {\n return\n }\n this._sendPatches()\n }\n\n _updateStats() {\n this.stats.recBps = this.stats.rec\n this.stats.rec = 0\n this.stats.recRTCBps = this.stats.recRTC\n this.stats.recRTC = 0\n this.stats.sendBps = this.stats.send\n this.stats.send = 0\n }\n\n _clear() {\n this.stats.sendBps = 0\n this.stats.recBps = 0\n this.stats.recRTC = 0\n this.stats.recRTCBps = 0\n this.stats.send = 0\n this.stats.rec = 0\n\n this.ID = 0\n this.documents = {}\n this._documentChanges = {}\n this._lastUpdateId = {}\n this.lastFullState = 0\n this.lastPatch = 0\n this._lastInterpolate = 0\n this.isPatched = false\n this.le = true\n }\n\n /*= INTERPOLATION ============================================================*/\n\n // to be called in display rate (like 60fps) to interpolate .position, .rotation and .scale\n interpolate() {\n let now = Date.now()\n let dt = now - this._lastInterpolate\n this._lastInterpolate = now\n if (dt <= 0 || dt > 200) { return }\n this.isInterpolated = true\n for (let name in this.documents) {\n let doc = this.documents[name]\n let entities = doc?.entities\n if (!entities) { continue }\n for (let id in entities) {\n let e: Entity = entities[id]\n if (e._lpostime1 && e._lpostime2) {\n let t1 = e._lpostime1\n let t2 = e._lpostime2\n const interval = t2 - t1;\n const elapsed = now - t1;\n e.pelapsed = elapsed\n /*if (elapsed > 5000) {\n } else */if (elapsed > 1000) {\n vec3.copy(e.position!, e._lpos2!)\n e._changed_position = now\n } else {\n const alpha = Math.max(0, elapsed / interval)\n vec3.lerp(this._dpos, e._lpos1!, e._lpos2!, alpha)\n vec3.lerp(e.position!, e.position!, this._dpos, 0.07)\n e._changed_position = now\n }\n }\n if (e._lrottime1 && e._lrottime2) {\n let t1 = e._lrottime1\n let t2 = e._lrottime2\n const interval = t2 - t1;\n const elapsed = now - t1;\n e.relapsed = elapsed\n /*if (elapsed > 5000) {\n } else */if (elapsed > 1000) {\n quat.copy(e.rotation!, e._lrot2!)\n e._changed_rotation = now\n } else {\n const alpha = Math.max(0, elapsed / interval)\n quat.slerp(this._drot, e._lrot1!, e._lrot2!, alpha)\n quat.slerp(e.rotation!, e.rotation!, this._drot, 0.07)\n e._changed_rotation = now\n }\n }\n\n }\n }\n this.isInterpolated = false\n }\n\n /*= CONNECTION ===============================================================*/\n\n subscribe(name: string) {\n this.documents[name] = {}\n this.send({ c: 'sub', n: name })\n }\n\n unsubscribe(name: string) {\n this.send({ c: 'unsub', n: name })\n delete this.documents[name]\n }\n\n connect() {\n if (this.isConnecting) {\n return\n }\n this.isConnecting = true\n this._clear()\n this.log('connecting...')\n\n this.socket = new WebSocket(this.url)\n\n // message received\n this.socket.onmessage = async (event: MessageEvent) => {\n let buffer = await event.data.arrayBuffer()\n this.stats.rec += buffer.byteLength\n let dec = await decompress(buffer)\n let decu = new Uint8Array(dec)\n let message = decode(decu)\n this._onMessage(message)\n }\n\n // connection closed\n this.socket.onclose = (_event: any) => {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n this.socket = null\n this.onDisconnect()\n if (this.allowWebRTC) {\n this._destroyWebRTC()\n }\n if (this.autoReconnect) {\n setTimeout(\n () => {\n this._reconnect()\n },\n 500 + Math.random() * 500\n )\n }\n }\n\n this.socket.onerror = (_event: Event) => {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n this.socket = null\n this.onDisconnect()\n if (this.allowWebRTC) {\n this._destroyWebRTC()\n }\n\n if (this.autoReconnect) {\n setTimeout(\n () => {\n this._reconnect()\n },\n 500 + Math.random() * 500\n )\n }\n }\n\n this.socket.onopen = async (_event: Event) => {\n this._clear()\n this.isConnecting = false\n this.isConnected = true\n this.lastFullState = 0\n this._ping()\n this.onConnect()\n if (this.allowWebRTC) {\n await this._initializeWebRTC()\n }\n }\n }\n\n disconnect() {\n this._clear()\n this.isConnected = false\n this.isConnecting = false\n this.lastFullState = 0\n if (this.socket) {\n this.socket.close()\n }\n this.socket = null\n }\n\n destroy() {\n this._clear()\n this.autoReconnect = false\n this.disconnect()\n this.socket = null\n if (this._siv) clearInterval(this._siv)\n if (this._loopiv) clearInterval(this._loopiv)\n }\n\n onConnect() {}\n\n onDisconnect() {}\n\n _reconnect() {\n if (!this.isConnected) {\n if (!this.isConnecting) {\n this.connect()\n }\n }\n }\n\n _ping() {\n if (this.isConnected) {\n this.send({ c: 'ping', ct: Date.now() })\n }\n }\n\n /*= MESSAGES =================================================================*/\n\n onChange(_name: string, _doc: Document | undefined, patch: any | undefined) {}\n\n onMessage(_message: Message) {}\n\n send(operation: any) {\n try {\n let enc = encode(operation)\n this.stats.send += enc.byteLength\n if (this.socket) {\n this.socket.send(enc)\n }\n } catch (e) {\n this.error('send failed', e)\n }\n }\n\n get document(): Document | undefined {\n let names:string = ''+Object.keys(this.documents)\n return this.documents[''+names[0]]\n }\n\n async _onMessage(message: Message) {\n let time = Date.now()\n if (message.c == 'full') {\n //this.log('full:', message)\n let name:string = ''+message.n\n let doc = message.doc\n this.documents[name] = doc\n this._decodeFastChanges(message)\n this.isPatched = false\n if (this.allowSync) {\n this.documents[name] = reactive(\n name,\n this.documents[name],\n this._onDocumentChange.bind(this)\n )\n }\n this.isPatched = false\n this.lastFullState = message.t\n this.le = message.le\n if (this._notifyChanges) {\n this.onChange(name, this.documents[name], null)\n }\n } else if (message.c == 'patch') {\n // patch\n this.lastPatch = message.t\n let name = message.n\n if (!this.documents[name]) {\n this.warn('Patch for unknown document', name)\n return\n }\n if (message.doc) {\n this.isPatched = true\n for (let op of message.doc) {\n let dop = msgop(op)\n try {\n applyOperation(this.documents[name], dop)\n } catch (e) {\n this.warn('applyOperation failed for', name, 'with op', dop, e)\n }\n }\n this.isPatched = false\n }\n if (this._notifyChanges) {\n this.onChange(name, this.documents[name], message.doc)\n }\n } else if (message.c == 'chunk') {\n //this.log('chunk', message)\n this._chunks[message.mid+'-'+message.seq] = message\n if (message.last) {\n let cfound = 0\n let ts = message.ts\n let cdata = new Uint8Array(ts)\n for (const cid in this._chunks) {\n let chunk = this._chunks[cid]\n if (chunk.mid == message.mid) {\n let offset = chunk.ofs\n let _csize = chunk.chs\n cdata.set(new Uint8Array(chunk.data), offset);\n cfound++\n delete this._chunks[cid]\n }\n }\n //this.log('found chunks ', cfound, 'of', message.seq + 1)\n if (cfound == message.seq + 1) {\n try {\n let cdec = await decompress(cdata)\n let cdecu = new Uint8Array(cdec)\n let nmessage = decode(cdecu)\n //this.log('decoded message', nmessage)\n this._onMessage(nmessage)\n } catch (error) {\n this.error('Error decoding chunks:', error)\n }\n } else {\n this.warn('missing chunks', cfound, 'of', message.seq + 1)\n }\n }\n } else if (message.c == 'fpatch') {\n time = Date.now()\n let name = message.n\n //this.log('fpatch', message)\n let doPatch = true\n if (!this._lastUpdateId[name]) {\n this._lastUpdateId[name] = message.u\n } else {\n if (this._lastUpdateId[name] < message.u) {\n let lp = message.u - this._lastUpdateId[name] - 1\n if (lp > 0) {\n this.warn('Lost ' + lp + ' updates')\n }\n this._lastUpdateId[name] = message.u\n } else if (this._lastUpdateId[name] > message.u) {\n // Handle the case where the server's update ID is older than the client's\n // This could be due to a network issue or a clock skew\n this.warn(`Received outdated update ID for document ${name}: ${message.u} < ${this._lastUpdateId[name]}`)\n doPatch = false\n }\n }\n if (doPatch) {\n this._decodeFastChanges(message)\n }\n } else if (message.c == 'pong') {\n this.ID = message.ID\n time = Date.now()\n let lastct = message.ct\n let ping = time - lastct\n let stime = message.t\n this.send({ c: 'peng', ct: Date.now(), st: stime })\n this.stats.stdiff = stime + ping / 2 - time\n this.stats.ping = ping\n this.log('ping', ping, 'ms', 'stdiff', this.stats.stdiff, 'ms')\n } else if (message.c == 'rtc-offer') {\n this.log(\"RTC: offer received:\", message);\n // You might need to handle this if the server sends offers\n } else if (message.c == 'rtc-answer') {\n this.log(\"RTC: answer received:\", message);\n try {\n const sessionDesc = new RTCSessionDescription({\n type: message.type,\n sdp: message.sdp,\n })\n if (this._peerConnection) {\n await this._peerConnection.setRemoteDescription(sessionDesc)\n }\n this.log(\"RTC: Remote description set successfully\");\n\n // Log the current state after setting remote description\n //\n //this.log(\"RTC: Current connection state:\", this._peerConnection.connectionState);\n //this.log(\"RTC: Current ICE connection state:\", this._peerConnection.iceConnectionState);\n for (let candidate of this._remoteCandidates) {\n try {\n await this._peerConnection?.addIceCandidate(candidate);\n this.log(\"RTC: Added remote ICE candidate:\", candidate);\n } catch (error) {\n this.error(\"RTC: Error adding remote ICE candidate:\", error);\n }\n }\n } catch (error) {\n this.error('RTC: Error setting remote description:', error)\n }\n } else if (message.c == 'rtc-candidate') {\n this.log(\"RTC: candidate received\", message);\n if (this._peerConnection && message.candidate) {\n this._remoteCandidates.push(message.candidate);\n }\n } else {\n this.onMessage(message)\n }\n }\n\n _onDocumentChange(name: string, op: any, target: any, path: string, value: any) {\n if (this.DEBUG) {\n this.log('Document change:', name, op, target, path, value)\n }\n if (this.isPatched || !this.allowSync) {\n return\n }\n if (path.indexOf('/_') >= 0) {\n return\n }\n if (!this._documentChanges[name]) {\n this._documentChanges[name] = []\n }\n this._documentChanges[name].push(opmsg(op, target, path, value))\n }\n\n _sendPatches() {\n for (let name in this._documentChanges) {\n let dc = this._documentChanges[name]\n if (!dc || dc.length == 0) {\n continue\n }\n let record: any = {\n n: name,\n c: 'sync',\n ct: Date.now(),\n p: null\n }\n\n if (dc.length > 0) {\n record.p = dc\n }\n this.send(record)\n dc.length = 0\n if (this._notifyChanges) {\n this.onChange(name, this.documents[''+name], record.p)\n }\n }\n }\n\n _decodeFastChanges(message: Message) {\n let time = Date.now()\n let name = message.n\n let fdata = message.fdata\n if (!fdata) {\n return\n }\n let doc = this.documents[name]\n if (!doc) {\n return\n }\n let entities = doc.entities\n if (!entities) {\n return\n }\n let origin = this.documents[''+name]?.origin\n if (!origin) {\n origin = [0, 0, 0]\n }\n for (let key in fdata) {\n let changes = fdata[key]\n if (changes.dict) {\n let pdata = changes.pdata\n let dict = changes.dict\n // Reverse the dictionary for lookup (value to key)\n let rdict: { [key: string]: string } = {};\n for (let key in dict) {\n rdict[dict[key]] = key;\n }\n let offset = 0\n\n while (offset < pdata.byteLength) {\n let id = ''+decode_uint32(pdata, offset)\n offset += 4\n let did = ''+decode_uint32(pdata, offset)\n offset += 4\n let e: Entity = entities[id]\n if (!e) {\n //this.log('Entity not found:', id)\n continue\n }\n let value = rdict[did]\n e[key] = value\n //this.log('FCHANGE', key, id, did, value, rdict)\n e['_changed_'+key] = time\n }\n } else {\n let pdata = changes.pdata\n let offset = 0\n while (offset < pdata.byteLength) {\n let id = ''+decode_uint32(pdata, offset)\n let e: Entity = entities[id]\n if (!e) {\n if (key == 'position') {\n offset += 13\n } else if (key == 'rotation') {\n offset += 8\n } else if (key == 'scale') {\n offset += 16\n }\n continue\n }\n offset += 4\n\n if (key == 'position') {\n if (!e._lpos2) {\n e._lpos1 = [0, 0, 0]\n e._lpos2 = [0, 0, 0]\n } else {\n e._lpos1![0] = e._lpos2[0]\n e._lpos1![1] = e._lpos2[1]\n e._lpos1![2] = e._lpos2[2]\n e._lpostime1 = e._lpostime2\n }\n e._lpostime2 = time\n e._lpos2[0] = origin[0] + decode_fp168(pdata, offset)\n offset += 3\n e._lpos2[1] = origin[1] + decode_fp168(pdata, offset)\n offset += 3\n e._lpos2[2] = origin[2] + decode_fp168(pdata, offset)\n offset += 3\n if (!e.position) {\n e.position = [\n e._lpos2[0],\n e._lpos2[1],\n e._lpos2[2],\n ]\n }\n } else if (key == 'rotation') {\n if (!e._lrot2) {\n e._lrot1 = [0, 0, 0, 1]\n e._lrot2 = [0, 0, 0, 1]\n } else {\n e._lrot1![0] = e._lrot2[0]\n e._lrot1![1] = e._lrot2[1]\n e._lrot1![2] = e._lrot2[2]\n e._lrot1![3] = e._lrot2[3]\n e._lrottime1 = e._lrottime2\n }\n e._lrottime2 = time\n e._lrot2[0] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[1] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[2] = decode_fp412(pdata, offset)\n offset += 2\n e._lrot2[3] = decode_fp412(pdata, offset)\n offset += 2\n quat.normalize(e._lrot2, e._lrot2)\n if (!e.rotation) {\n e.rotation = [\n e._lrot2[0],\n e._lrot2[1],\n e._lrot2[2],\n e._lrot2[3],\n ]\n }\n } else if (key == 'scale') {\n if (!e._lsca2) {\n e._lsca1 = [0, 0, 0]\n e._lsca2 = [0, 0, 0]\n } else {\n e._lsca1![0] = e._lsca2[0]\n e._lsca1![1] = e._lsca2[1]\n e._lsca1![2] = e._lsca2[2]\n e._lscatime1 = e._lscatime2\n }\n e._lscatime2 = time\n e._lsca2[0] = decode_fp1616(pdata, offset)\n offset += 4\n e._lsca2[1] = decode_fp1616(pdata, offset)\n offset += 4\n e._lsca2[2] = decode_fp1616(pdata, offset)\n offset += 4\n if (!e.sca) {\n e.sca = [\n e._lsca2[0],\n e._lsca2[1],\n e._lsca2[2],\n ]\n }\n }\n }\n }\n }\n }\n\n /*= WEBRTC ===================================================================*/\n\n sendRTC(message: Message) {\n if (this._dataChannel && this._dataChannel.readyState === 'open') {\n this._dataChannel.send(encode(message))\n }\n }\n\n _onRTCConnect() {\n this.log('RTC: Connected')\n this.send({ c: 'test', message: 'Hello RTC from client' })\n }\n\n _onRTCDisconnect() {\n this._webRTCConnected = false\n this.log('RTC: Disconnected')\n }\n\n async _onRTCMessage(data: ArrayBuffer) {\n this.stats.recRTC += data.byteLength\n let datau = new Uint8Array(data)\n let dec = await decompress(datau)\n let decu = new Uint8Array(dec)\n let message = decode(decu)\n this._onMessage(message)\n }\n\n async _initializeWebRTC() {\n //this.log(\"RTC: _initializeWebRTC\")\n this._peerConnection = null\n this._candidates = []\n this._remoteCandidates = []\n this._offerSent = false\n try {\n // Create RTCPeerConnection with more comprehensive STUN server list\n this._peerConnection = new RTCPeerConnection({\n iceServers: [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:stun.cloudflare.com:3478' },\n { urls: 'stun:freestun.net:3478' },\n ],\n iceCandidatePoolSize: 10,\n })\n\n //this.log(\"RTC: peerConnection created\", this._peerConnection)\n\n // Handle ICE candidates\n this._peerConnection.onicecandidate = (event: RTCPeerConnectionIceEvent) => {\n //this.log(\"RTC: onicecandidate\", event.candidate)\n if (event.candidate) {\n this._candidates.push(event.candidate)\n } else {\n this.log(\"RTC: ICE candidate gathering complete\")\n }\n }\n\n // Log connection state changes\n this._peerConnection.onconnectionstatechange = () => {\n //this.log(`RTC: Connection state changed: ${this._peerConnection.connectionState}`)\n if (this._peerConnection && this._peerConnection.connectionState === 'connected') {\n this._webRTCConnected = true\n this.log('RTC: Peer connection established!')\n } else if (\n this._peerConnection && (\n this._peerConnection.connectionState === 'failed' ||\n this._peerConnection.connectionState === 'disconnected' ||\n this._peerConnection.connectionState === 'closed')\n ) {\n this._webRTCConnected = false\n this.log('RTC: Peer connection closed or failed')\n }\n }\n\n this._peerConnection.onicegatheringstatechange = () => {\n this.log(`RTC: ICE gathering state. _candidates:`, this._candidates.length, this._peerConnection?.iceGatheringState)\n if (this._peerConnection?.iceGatheringState == 'complete' && this._offerSent) {\n for (let candidate of this._candidates) {\n this.send({\n c: 'rtc-candidate',\n type: 'ice-candidate',\n candidate: candidate,\n })\n }\n }\n }\n\n this._peerConnection.oniceconnectionstatechange = () => {\n //this.log(`RTC: ICE connection state: ${this._peerConnection.iceConnectionState}`)\n\n // This is critical - when ICE succeeds, the connection should be established\n if (\n this._peerConnection && (\n this._peerConnection.iceConnectionState === 'connected' ||\n this._peerConnection.iceConnectionState === 'completed')\n ) {\n //this.log(\"RTC: ICE connection established!\")\n }\n }\n\n // Create a data channel on our side as well (belt and suspenders approach)\n this._dataChannel = this._peerConnection.createDataChannel(\n 'clientchannel',\n {\n ordered: true,\n maxRetransmits: 1,\n }\n )\n\n this._dataChannel.onopen = () => {\n this._onRTCConnect()\n }\n\n this._dataChannel.onclose = () => {\n this._onRTCDisconnect()\n }\n\n this._dataChannel.onerror = (_error: Event) => {\n this.error('RTC: Client data channel error', _error)\n }\n\n // Handle data channels created by the server\n this._peerConnection.ondatachannel = (event: RTCDataChannelEvent) => {\n //this.log(\"RTC: Server data channel received\", event.channel.label);\n const dataChannel = event.channel\n this._serverDataChannel = dataChannel\n\n dataChannel.onopen = () => {\n //this.log(\"RTC: Server data channel open\");\n }\n\n dataChannel.onclose = () => {\n //this.log(\"RTC: Server data channel closed\");\n }\n\n dataChannel.onerror = (_error: Event) => {\n //this.error(\"RTC: Server data channel error\", error);\n }\n\n dataChannel.onmessage = (event: MessageEvent) => {\n this._onRTCMessage(event.data)\n }\n }\n\n // Create and send offer with specific constraints\n const offerOptions: RTCOfferOptions = {\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n iceRestart: true,\n }\n\n const offer = await this._peerConnection.createOffer(offerOptions)\n //this.log(\"RTC: our offer:\", offer);\n await this._peerConnection.setLocalDescription(offer)\n\n // Wait a moment to ensure the local description is set\n await new Promise((resolve) => setTimeout(resolve, 100))\n\n let ld = this._peerConnection.localDescription\n //this.log(\"RTC: our localDescription\", ld);\n\n if (ld) {\n const offerPayload = {\n c: 'rtc-offer',\n type: ld.type,\n sdp: ld.sdp,\n }\n //this.log(\"RTC: our offer payload\", offerPayload);\n this.send(offerPayload)\n this._offerSent = true\n }\n\n // Set a timeout to check connection status\n setTimeout(() => {\n if (!this._webRTCConnected && this._peerConnection) {\n /*\n this.log(\"RTC: Connection not established after timeout, current states:\");\n this.log(\"Connection state:\", this._peerConnection.connectionState);\n this.log(\"ICE connection state:\", this._peerConnection.iceConnectionState);\n this.log(\"ICE gathering state:\", this._peerConnection.iceGatheringState);\n */\n // Attempt to restart ICE if needed\n if (this._peerConnection.iceConnectionState === 'failed') {\n this.log('RTC: Attempting ICE restart')\n this._restartIce()\n }\n }\n }, 5000)\n } catch (error) {\n this.error('RTC: error:', error)\n }\n }\n\n // Add this method to restart ICE if needed\n async _restartIce() {\n try {\n const offerOptions = {\n offerToReceiveAudio: false,\n offerToReceiveVideo: false,\n iceRestart: true,\n }\n\n const offer = await this._peerConnection?.createOffer(offerOptions)\n await this._peerConnection?.setLocalDescription(offer)\n\n const offerPayload = {\n c: 'rtc-offer',\n type: offer?.type,\n sdp: offer?.sdp,\n }\n //this.log(\"RTC: ICE restart offer payload\", offerPayload);\n this.send(offerPayload)\n } catch (error) {\n //this.error(\"RTC: Error during ICE restart:\", error);\n }\n }\n\n async _destroyWebRTC() {\n if (this._peerConnection) {\n if (this._peerConnection.dataChannel) {\n this._peerConnection.dataChannel.close()\n }\n this._peerConnection.close()\n this._peerConnection = null\n }\n if (this._dataChannel) {\n this._dataChannel.close()\n this._dataChannel = null\n }\n this._webRTCConnected = false\n }\n}\n","import { Packr } from 'msgpackr';\nimport { FLOAT32_OPTIONS } from 'msgpackr';\nconst { ALWAYS } = FLOAT32_OPTIONS;\n\nlet packr = new Packr({\n useFloat32: ALWAYS\n});\n\nexport function encode(obj: any): Uint8Array {\n return packr.pack(obj)\n}\n\nexport function decode(data: Uint8Array): any {\n return packr.unpack(data)\n}\n\ntype ReactiveCallback = (name: string, operation: string, target: any, path: string, value: any) => void;\n\nexport function reactive(name: string, object: any, callback: ReactiveCallback, path: string = '', excludedProperties: Record<string, boolean> | false = false): any {\n if (object === null || typeof object !== 'object') {\n //console.log('--- Type not object', typeof object)\n return object\n }\n\n function isReactive(p: string): boolean {\n let r = true\n if (p.startsWith('_')) {\n r = false\n }\n if (excludedProperties) {\n if (excludedProperties[p]) {\n r = false\n }\n }\n if (path == '/entities') {\n r = false\n }\n return r\n }\n\n for (const property in object) {\n if (isReactive(property)) {\n //console.log(`path '${path}', prop '${property}' is reactive`)\n object[property] = reactive(\n name,\n object[property],\n callback,\n path + '/' + property,\n excludedProperties\n )\n } else {\n //console.log(`--- path '${path}', property '${property}' is NOT reactive`)\n }\n }\n //console.log(`path '${path}' is reactive`)\n return new Proxy(object, {\n get(target: any, property: string | symbol, receiver: any): any { // ...arguments\n return Reflect.get(target, property, receiver)\n },\n set(target: any, property: string | symbol, value: any): boolean {\n let newvalue: any\n let pn = path + '/' + String(property)\n if (isReactive(String(property))) {\n newvalue = reactive(name, value, callback, pn, excludedProperties)\n callback(name, 'replace', target, pn, newvalue)\n } else {\n newvalue = value\n }\n return Reflect.set(target, property, newvalue)\n },\n deleteProperty(target: any, property: string | symbol): boolean {\n let pn = path + '/' + String(property)\n if (isReactive(String(property))) {\n callback(name, 'remove', target, pn, null)\n }\n delete target[property]\n return true\n },\n })\n\n}\n\nexport function deepGet(obj: any, path: string): any {\n //path = path.replace(/^\\/+/, '')\n let paths = ('' + path).split('/').filter((p) => p)\n let len = paths.length\n for (let i = 0; i < len; i++) {\n if (obj[paths[i]!] == undefined) {\n return undefined\n } else {\n obj = obj[paths[i]!]\n }\n }\n return obj\n}\n\nexport function deepSet(obj: any, path: string, value: any): void {\n //path = path.replace(/^\\/+/, '')\n let paths = ('' + path).split('/').filter((p) => p)\n let len = paths.length\n let i: number\n for (i = 0; i < len - 1; i++) {\n obj = obj[paths[i]!]\n }\n obj[paths[i]!] = value\n}\n\n// recursive clone oject, without properties that starts with _ (or __)\n\nexport function clonewo_(obj: any, excludeStart: string | Record<string, boolean> = '_'): any {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n function isExcluded(key: string): boolean {\n let e = false\n if (typeof (excludeStart) == 'string' && key.startsWith(excludeStart)) {\n e = true\n } else if (typeof(excludeStart) == 'object') {\n if (excludeStart[key] || key.startsWith('_')) {\n e = true\n }\n }\n return e\n }\n\n if (obj instanceof Map) {\n const mapClone = new Map()\n Array.from(obj.entries()).forEach(([key, value]) => {\n mapClone.set(clonewo_(key, excludeStart), clonewo_(value, excludeStart))\n })\n return mapClone\n }\n\n let clone: any\n if (Array.isArray(obj)) {\n clone = []\n for (let i = 0; i < obj.length; i++) {\n clone[i] = clonewo_(obj[i], excludeStart)\n }\n } else {\n clone = {} as Record<string, any>\n for (let key in obj) {\n if (obj.hasOwnProperty(key) && !isExcluded(key)) {\n if (typeof obj[key] === 'object') {\n clone[key] = clonewo_(obj[key], excludeStart)\n } else {\n clone[key] = obj[key]\n }\n }\n }\n }\n\n return clone\n}\n\nexport function limitPrecision(obj: any): any {\n if (Array.isArray(obj)) {\n return obj.map(limitPrecision)\n } else if (obj !== null && typeof obj === 'object') {\n const result: Record<string, any> = {}\n for (const key in obj) {\n result[key] = limitPrecision(obj[key])\n }\n return result\n } else if (typeof obj === 'number') {\n if (Number.isInteger(obj)) {\n return obj\n } else {\n // Limit to max 3 decimal digits, not fixed\n return parseFloat(obj.toFixed(3))\n }\n } else {\n return obj\n }\n}\n\nexport function msgop(op: any): any {\n let nop: any = {}\n if (!op.o) {\n nop.op = 'replace'\n } else {\n nop.op = ({\n a: 'add',\n r: 'remove',\n d: 'delete',\n t: 'test',\n } as Record<string, string>)[op.o]\n }\n nop.path = op.p\n nop.value = op.v\n return nop\n}\n\nexport function opmsg(op: string, target: any, path: string, value: any): any {\n let c: any = { p: path, v: value }\n if (op != 'replace') {\n c.o = ({\n add: 'a',\n remove: 'r',\n delete: 'd',\n test: 't',\n } as Record<string, string>)[op]\n }\n return c\n}\n\n// a function that converts an int to a hexa string\n// (8 characters long)\nexport function int2hex(int: number): string {\n return int.toString(16)\n}\n\n// a function that converts a hexa string to an int\nexport function hex2int(str: string): bigint {\n if (str.length % 2) {\n str = '0' + str\n }\n return BigInt('0x' + str)\n}\n\n// - Fixed point encoding/decoding functions\n\n// 32-bit unsigned integer encoding\nexport function encode_uint32(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(4)\n }\n let p = offset + 3\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n// 32-bit unsigned integer decoding\nexport function decode_uint32(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (\n ((byteArray[p++]! & 0x7f) << 24) |\n (byteArray[p++]! << 16) |\n (byteArray[p++]! << 8) |\n byteArray[p]!\n )\n}\n\n// 24-bit unsigned integer encoding\nexport function encode_uint24(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(3)\n }\n let p = offset + 2\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n\n// 24-bit unsigned integer decoding\nexport function decode_uint24(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (\n (byteArray[p++]! << 16) |\n (byteArray[p++]! << 8) |\n byteArray[p]!\n )\n}\n\n// 16-bit unsigned integer encoding\nexport function encode_uint16(uint: number, byteArray?: Uint8Array, offset: number = 0): Uint8Array {\n if (!byteArray) {\n byteArray = new Uint8Array(2)\n }\n let p = offset + 1\n byteArray[p--] = uint & 0xff\n uint >>= 8\n byteArray[p] = uint\n return byteArray\n}\n\n// 16-bit unsigned integer decoding\nexport function decode_uint16(byteArray: Uint8Array, offset: number = 0): number {\n let p = offset\n return (byteArray[p++]! << 8) | byteArray[p]!\n}\n\n// 24.8 bit ====================================================================\n\n// 24.8-bit fixed point encoding\nexport function encode_fp248(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint32(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 24.8-bit fixed point decoding\nexport function decode_fp248(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint32(byteArray, offset)\n return fp / divider\n}\n\n// 16.8 bit ====================================================================\n\n// 16.8-bit fixed point encoding (3 bytes)\nexport function encode_fp168(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint24(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 16.8-bit fixed point decoding (3 bytes)\nexport function decode_fp168(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint24(byteArray, offset)\n return fp / divider\n}\n\n// 16.16 bit ===================================================================\n\n// 16.16-bit fixed point encoding\nexport function encode_fp1616(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 65536)\n encode_uint32(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 16.16-bit fixed point decoding\nexport function decode_fp1616(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -65536 : 65536\n byteArray[offset]! &= 0x7f\n const fp = decode_uint32(byteArray, offset)\n return fp / divider\n}\n\n// 8.8 bit =====================================================================\n\n// 8.8-bit fixed point encoding\nexport function encode_fp88(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 256)\n encode_uint16(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 8.8-bit fixed point decoding\nexport function decode_fp88(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -256 : 256\n byteArray[offset]! &= 0x7f\n const fp = decode_uint16(byteArray, offset)\n return fp / divider\n}\n\n// 4.12 bit ====================================================================\n\n// 4.12-bit fixed point encoding\nexport function encode_fp412(float: number, byteArray?: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 4096)\n encode_uint16(fp, byteArray, offset)\n if (float < 0 && byteArray) {\n byteArray[offset]! |= 0x80\n }\n}\n\n// 4.12-bit fixed point decoding\nexport function decode_fp412(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -4096 : 4096\n byteArray[offset]! &= 0x7f\n const fp = decode_uint16(byteArray, offset)\n return fp / divider\n}\n\n// 1.7 bit =====================================================================\n\n// 1.7-bit fixed point encoding\nexport function encode_fp17(float: number, byteArray: Uint8Array, offset: number = 0): void {\n const fp = Math.round(Math.abs(float) * 128)\n byteArray[offset] = fp\n if (float < 0) {\n byteArray[offset] |= 0x80\n }\n}\n\n// 1.7-bit fixed point decoding\nexport function decode_fp17(byteArray: Uint8Array, offset: number = 0): number {\n const divider = (byteArray[offset]! & 0x80) === 0x80 ? -128.0 : 128.0\n byteArray[offset]! &= 0x7f\n return byteArray[offset]! / divider\n}\n","const browserFormat = 'gzip'\n\nconst MIN_COMPRESSED_BUFFER_SIZE = 256\n\nexport async function compress(buffer:Uint8Array<ArrayBufferLike>) {\n if (buffer.byteLength <= MIN_COMPRESSED_BUFFER_SIZE) return buffer\n if (typeof CompressionStream !== 'undefined') {\n const cs = new CompressionStream(browserFormat)\n const compressed = await new Response(\n new Blob([buffer]).stream().pipeThrough(cs)\n ).arrayBuffer()\n return compressed\n } else {\n throw new Error('CompressionStream not supported')\n }\n}\n\nexport async function decompress(buffer:Uint8Array<ArrayBufferLike>) {\n if (typeof DecompressionStream !== 'undefined') {\n try {\n const ds = new DecompressionStream(browserFormat)\n const decompressed = await new Response(\n new Blob([buffer]).stream().pipeThrough(ds)\n ).arrayBuffer()\n //console.log(` ${buffer.byteLength} -> ${decompressed.byteLength}`)\n return decompressed\n } catch (e) {\n //console.error('Decompression failed:', e)\n return buffer\n }\n } else {\n throw new Error('DecompressionStream not supported')\n }\n}\n"],"mappings":"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","names":["import_msgpackr","key","event"]}
|
package/dist/client.js
CHANGED
|
@@ -496,7 +496,7 @@ var TopazCubeClient = class {
|
|
|
496
496
|
try {
|
|
497
497
|
applyOperation(this.documents[name], dop);
|
|
498
498
|
} catch (e) {
|
|
499
|
-
this.
|
|
499
|
+
this.warn("applyOperation failed for", name, "with op", dop, e);
|
|
500
500
|
}
|
|
501
501
|
}
|
|
502
502
|
this.isPatched = false;
|