@rapierphysicsplugin/client 1.0.0

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.
Files changed (83) hide show
  1. package/dist/__tests__/clock-sync.test.d.ts +2 -0
  2. package/dist/__tests__/clock-sync.test.d.ts.map +1 -0
  3. package/dist/__tests__/clock-sync.test.js +63 -0
  4. package/dist/__tests__/clock-sync.test.js.map +1 -0
  5. package/dist/__tests__/interpolator.test.d.ts +2 -0
  6. package/dist/__tests__/interpolator.test.d.ts.map +1 -0
  7. package/dist/__tests__/interpolator.test.js +82 -0
  8. package/dist/__tests__/interpolator.test.js.map +1 -0
  9. package/dist/__tests__/state-reconciler.test.d.ts +2 -0
  10. package/dist/__tests__/state-reconciler.test.d.ts.map +1 -0
  11. package/dist/__tests__/state-reconciler.test.js +86 -0
  12. package/dist/__tests__/state-reconciler.test.js.map +1 -0
  13. package/dist/clock-sync.d.ts +17 -0
  14. package/dist/clock-sync.d.ts.map +1 -0
  15. package/dist/clock-sync.js +63 -0
  16. package/dist/clock-sync.js.map +1 -0
  17. package/dist/index.d.ts +10 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +8 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/input-manager.d.ts +18 -0
  22. package/dist/input-manager.d.ts.map +1 -0
  23. package/dist/input-manager.js +62 -0
  24. package/dist/input-manager.js.map +1 -0
  25. package/dist/interpolator.d.ts +35 -0
  26. package/dist/interpolator.d.ts.map +1 -0
  27. package/dist/interpolator.js +198 -0
  28. package/dist/interpolator.js.map +1 -0
  29. package/dist/networked-rapier-plugin.d.ts +82 -0
  30. package/dist/networked-rapier-plugin.d.ts.map +1 -0
  31. package/dist/networked-rapier-plugin.js +698 -0
  32. package/dist/networked-rapier-plugin.js.map +1 -0
  33. package/dist/rapier-body-ops.d.ts +27 -0
  34. package/dist/rapier-body-ops.d.ts.map +1 -0
  35. package/dist/rapier-body-ops.js +208 -0
  36. package/dist/rapier-body-ops.js.map +1 -0
  37. package/dist/rapier-collision-ops.d.ts +6 -0
  38. package/dist/rapier-collision-ops.d.ts.map +1 -0
  39. package/dist/rapier-collision-ops.js +200 -0
  40. package/dist/rapier-collision-ops.js.map +1 -0
  41. package/dist/rapier-constraint-ops.d.ts +29 -0
  42. package/dist/rapier-constraint-ops.d.ts.map +1 -0
  43. package/dist/rapier-constraint-ops.js +286 -0
  44. package/dist/rapier-constraint-ops.js.map +1 -0
  45. package/dist/rapier-plugin.d.ts +145 -0
  46. package/dist/rapier-plugin.d.ts.map +1 -0
  47. package/dist/rapier-plugin.js +263 -0
  48. package/dist/rapier-plugin.js.map +1 -0
  49. package/dist/rapier-shape-ops.d.ts +21 -0
  50. package/dist/rapier-shape-ops.d.ts.map +1 -0
  51. package/dist/rapier-shape-ops.js +314 -0
  52. package/dist/rapier-shape-ops.js.map +1 -0
  53. package/dist/rapier-types.d.ts +58 -0
  54. package/dist/rapier-types.d.ts.map +1 -0
  55. package/dist/rapier-types.js +4 -0
  56. package/dist/rapier-types.js.map +1 -0
  57. package/dist/state-reconciler.d.ts +28 -0
  58. package/dist/state-reconciler.d.ts.map +1 -0
  59. package/dist/state-reconciler.js +119 -0
  60. package/dist/state-reconciler.js.map +1 -0
  61. package/dist/sync-client.d.ts +110 -0
  62. package/dist/sync-client.d.ts.map +1 -0
  63. package/dist/sync-client.js +514 -0
  64. package/dist/sync-client.js.map +1 -0
  65. package/package.json +21 -0
  66. package/src/__tests__/clock-sync.test.ts +72 -0
  67. package/src/__tests__/interpolator.test.ts +98 -0
  68. package/src/__tests__/state-reconciler.test.ts +102 -0
  69. package/src/clock-sync.ts +77 -0
  70. package/src/index.ts +9 -0
  71. package/src/input-manager.ts +72 -0
  72. package/src/interpolator.ts +256 -0
  73. package/src/networked-rapier-plugin.ts +909 -0
  74. package/src/rapier-body-ops.ts +251 -0
  75. package/src/rapier-collision-ops.ts +229 -0
  76. package/src/rapier-constraint-ops.ts +327 -0
  77. package/src/rapier-plugin.ts +364 -0
  78. package/src/rapier-shape-ops.ts +369 -0
  79. package/src/rapier-types.ts +60 -0
  80. package/src/state-reconciler.ts +151 -0
  81. package/src/sync-client.ts +640 -0
  82. package/tsconfig.json +12 -0
  83. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,514 @@
1
+ import { MessageType, encodeMessage, decodeServerMessage, FIELD_POSITION, FIELD_ROTATION, FIELD_LIN_VEL, FIELD_ANG_VEL, OPCODE_MESH_BINARY, decodeMeshBinary, OPCODE_GEOMETRY_DEF, OPCODE_MESH_REF, OPCODE_MATERIAL_DEF, OPCODE_TEXTURE_DEF, decodeGeometryDef, decodeMeshRef, decodeMaterialDef, decodeTextureDef, } from '@rapierphysicsplugin/shared';
2
+ import { ClockSyncClient } from './clock-sync.js';
3
+ import { StateReconciler } from './state-reconciler.js';
4
+ import { Interpolator } from './interpolator.js';
5
+ import { InputManager } from './input-manager.js';
6
+ export class PhysicsSyncClient {
7
+ constructor() {
8
+ this.ws = null;
9
+ this.clientId = null;
10
+ this.roomId = null;
11
+ // Body ID mapping for numeric wire format
12
+ this.indexToId = new Map();
13
+ this.idToIndex = new Map();
14
+ // Full state map — merges partial delta updates into complete body states
15
+ this.fullStateMap = new Map();
16
+ this._simulationRunning = false;
17
+ this._bytesSent = 0;
18
+ this._bytesReceived = 0;
19
+ this.stateUpdateCallbacks = [];
20
+ this.bodyAddedCallbacks = [];
21
+ this.bodyRemovedCallbacks = [];
22
+ this.simulationStartedCallbacks = [];
23
+ this.collisionEventsCallbacks = [];
24
+ this.constraintAddedCallbacks = [];
25
+ this.constraintRemovedCallbacks = [];
26
+ this.meshBinaryCallbacks = [];
27
+ this.geometryDefCallbacks = [];
28
+ this.meshRefCallbacks = [];
29
+ this.materialDefCallbacks = [];
30
+ this.textureDefCallbacks = [];
31
+ this.connectResolve = null;
32
+ this.connectReject = null;
33
+ this.joinResolve = null;
34
+ this.createResolve = null;
35
+ this.clockSync = new ClockSyncClient();
36
+ const interpolator = new Interpolator();
37
+ this.reconciler = new StateReconciler(interpolator);
38
+ this.inputManager = new InputManager();
39
+ }
40
+ connect(url) {
41
+ return new Promise((resolve, reject) => {
42
+ this.connectResolve = resolve;
43
+ this.connectReject = reject;
44
+ this.ws = new WebSocket(url);
45
+ this.ws.binaryType = 'arraybuffer';
46
+ this.ws.onopen = () => {
47
+ this.clockSync.start((data) => {
48
+ this._bytesSent += data.byteLength;
49
+ this.ws?.send(data);
50
+ });
51
+ this.connectResolve?.();
52
+ this.connectResolve = null;
53
+ this.connectReject = null;
54
+ };
55
+ this.ws.onmessage = async (event) => {
56
+ let buf;
57
+ if (event.data instanceof ArrayBuffer) {
58
+ buf = new Uint8Array(event.data);
59
+ }
60
+ else if (event.data instanceof Blob) {
61
+ buf = new Uint8Array(await event.data.arrayBuffer());
62
+ }
63
+ else {
64
+ console.warn('[SyncClient] Unexpected message data type:', typeof event.data);
65
+ return;
66
+ }
67
+ this._bytesReceived += buf.byteLength;
68
+ try {
69
+ // Intercept mesh binary messages directly — skip normal decode path
70
+ if (buf[0] === OPCODE_MESH_BINARY) {
71
+ const decoded = decodeMeshBinary(buf);
72
+ const msg = { type: MessageType.MESH_BINARY, ...decoded };
73
+ for (const cb of this.meshBinaryCallbacks) {
74
+ cb(msg);
75
+ }
76
+ return;
77
+ }
78
+ // Intercept geometry def messages
79
+ if (buf[0] === OPCODE_GEOMETRY_DEF) {
80
+ const decoded = decodeGeometryDef(buf);
81
+ for (const cb of this.geometryDefCallbacks) {
82
+ cb(decoded);
83
+ }
84
+ return;
85
+ }
86
+ // Intercept mesh ref messages
87
+ if (buf[0] === OPCODE_MESH_REF) {
88
+ const decoded = decodeMeshRef(buf);
89
+ for (const cb of this.meshRefCallbacks) {
90
+ cb(decoded);
91
+ }
92
+ return;
93
+ }
94
+ // Intercept material def messages
95
+ if (buf[0] === OPCODE_MATERIAL_DEF) {
96
+ const decoded = decodeMaterialDef(buf);
97
+ for (const cb of this.materialDefCallbacks) {
98
+ cb(decoded);
99
+ }
100
+ return;
101
+ }
102
+ // Intercept texture def messages
103
+ if (buf[0] === OPCODE_TEXTURE_DEF) {
104
+ const decoded = decodeTextureDef(buf);
105
+ for (const cb of this.textureDefCallbacks) {
106
+ cb(decoded);
107
+ }
108
+ return;
109
+ }
110
+ const message = decodeServerMessage(buf, this.indexToId);
111
+ this.handleMessage(message);
112
+ }
113
+ catch (err) {
114
+ console.warn(`[SyncClient] Failed to decode server message (${buf.byteLength} bytes, opcode=0x${buf[0]?.toString(16)}):`, err);
115
+ }
116
+ };
117
+ this.ws.onclose = () => {
118
+ this.clockSync.stop();
119
+ this.inputManager.stop();
120
+ };
121
+ this.ws.onerror = (event) => {
122
+ this.connectReject?.(new Error('WebSocket connection failed'));
123
+ this.connectResolve = null;
124
+ this.connectReject = null;
125
+ };
126
+ });
127
+ }
128
+ createRoom(roomId, initialBodies, gravity) {
129
+ return new Promise((resolve, reject) => {
130
+ if (!this.ws) {
131
+ reject(new Error('Not connected'));
132
+ return;
133
+ }
134
+ this.createResolve = resolve;
135
+ this.send({
136
+ type: MessageType.CREATE_ROOM,
137
+ roomId,
138
+ initialBodies,
139
+ gravity,
140
+ });
141
+ });
142
+ }
143
+ joinRoom(roomId) {
144
+ return new Promise((resolve, reject) => {
145
+ if (!this.ws) {
146
+ reject(new Error('Not connected'));
147
+ return;
148
+ }
149
+ this.joinResolve = resolve;
150
+ this.send({
151
+ type: MessageType.JOIN_ROOM,
152
+ roomId,
153
+ });
154
+ });
155
+ }
156
+ leaveRoom() {
157
+ if (!this.ws || !this.roomId)
158
+ return;
159
+ this.send({ type: MessageType.LEAVE_ROOM });
160
+ this.roomId = null;
161
+ this.inputManager.stop();
162
+ this.reconciler.clear();
163
+ this.fullStateMap.clear();
164
+ this.indexToId.clear();
165
+ this.idToIndex.clear();
166
+ }
167
+ sendInput(actions) {
168
+ for (const action of actions) {
169
+ this.inputManager.queueAction(action);
170
+ }
171
+ }
172
+ addLocalBody(bodyId) {
173
+ this.reconciler.addLocalBody(bodyId);
174
+ }
175
+ removeLocalBody(bodyId) {
176
+ this.reconciler.removeLocalBody(bodyId);
177
+ }
178
+ addBody(body) {
179
+ if (!this.ws)
180
+ return;
181
+ this.send({ type: MessageType.ADD_BODY, body });
182
+ }
183
+ removeBody(bodyId) {
184
+ if (!this.ws)
185
+ return;
186
+ this.send({ type: MessageType.REMOVE_BODY, bodyId });
187
+ }
188
+ addConstraint(constraint) {
189
+ if (!this.ws)
190
+ return;
191
+ this.send({ type: MessageType.ADD_CONSTRAINT, constraint });
192
+ }
193
+ removeConstraint(constraintId) {
194
+ if (!this.ws)
195
+ return;
196
+ this.send({ type: MessageType.REMOVE_CONSTRAINT, constraintId });
197
+ }
198
+ onStateUpdate(callback) {
199
+ this.stateUpdateCallbacks.push(callback);
200
+ }
201
+ onBodyAdded(callback) {
202
+ this.bodyAddedCallbacks.push(callback);
203
+ }
204
+ onBodyRemoved(callback) {
205
+ this.bodyRemovedCallbacks.push(callback);
206
+ }
207
+ onSimulationStarted(callback) {
208
+ this.simulationStartedCallbacks.push(callback);
209
+ }
210
+ onCollisionEvents(callback) {
211
+ this.collisionEventsCallbacks.push(callback);
212
+ }
213
+ onConstraintAdded(callback) {
214
+ this.constraintAddedCallbacks.push(callback);
215
+ }
216
+ onConstraintRemoved(callback) {
217
+ this.constraintRemovedCallbacks.push(callback);
218
+ }
219
+ onMeshBinary(callback) {
220
+ this.meshBinaryCallbacks.push(callback);
221
+ }
222
+ onGeometryDef(callback) {
223
+ this.geometryDefCallbacks.push(callback);
224
+ }
225
+ onMeshRef(callback) {
226
+ this.meshRefCallbacks.push(callback);
227
+ }
228
+ onMaterialDef(callback) {
229
+ this.materialDefCallbacks.push(callback);
230
+ }
231
+ onTextureDef(callback) {
232
+ this.textureDefCallbacks.push(callback);
233
+ }
234
+ /** Send pre-encoded binary mesh data directly over the WebSocket (no msgpackr wrapping). */
235
+ sendMeshBinary(encoded) {
236
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
237
+ this._bytesSent += encoded.byteLength;
238
+ this.ws.send(encoded);
239
+ }
240
+ }
241
+ /** Send pre-encoded GEOMETRY_DEF directly over the WebSocket. */
242
+ sendGeometryDef(encoded) {
243
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
244
+ this._bytesSent += encoded.byteLength;
245
+ this.ws.send(encoded);
246
+ }
247
+ }
248
+ /** Send pre-encoded MESH_REF directly over the WebSocket. */
249
+ sendMeshRef(encoded) {
250
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
251
+ this._bytesSent += encoded.byteLength;
252
+ this.ws.send(encoded);
253
+ }
254
+ }
255
+ /** Send pre-encoded MATERIAL_DEF directly over the WebSocket. */
256
+ sendMaterialDef(encoded) {
257
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
258
+ this._bytesSent += encoded.byteLength;
259
+ this.ws.send(encoded);
260
+ }
261
+ }
262
+ /** Send pre-encoded TEXTURE_DEF directly over the WebSocket. */
263
+ sendTextureDef(encoded) {
264
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
265
+ this._bytesSent += encoded.byteLength;
266
+ this.ws.send(encoded);
267
+ }
268
+ }
269
+ startSimulation() {
270
+ if (!this.ws)
271
+ return;
272
+ this.send({ type: MessageType.START_SIMULATION });
273
+ }
274
+ get simulationRunning() {
275
+ return this._simulationRunning;
276
+ }
277
+ /** Total number of bodies the client knows about (including sleeping/unchanged ones) */
278
+ get totalBodyCount() {
279
+ return this.fullStateMap.size;
280
+ }
281
+ disconnect() {
282
+ this.clockSync.stop();
283
+ this.inputManager.stop();
284
+ this.reconciler.clear();
285
+ this.fullStateMap.clear();
286
+ this.indexToId.clear();
287
+ this.idToIndex.clear();
288
+ this.ws?.close();
289
+ this.ws = null;
290
+ this.roomId = null;
291
+ this.clientId = null;
292
+ }
293
+ initBodyIdMap(bodyIdMap) {
294
+ this.indexToId.clear();
295
+ this.idToIndex.clear();
296
+ for (const [id, index] of Object.entries(bodyIdMap)) {
297
+ this.indexToId.set(index, id);
298
+ this.idToIndex.set(id, index);
299
+ }
300
+ }
301
+ addBodyIdMapping(id, index) {
302
+ this.indexToId.set(index, id);
303
+ this.idToIndex.set(id, index);
304
+ }
305
+ initFullState(bodies) {
306
+ this.fullStateMap.clear();
307
+ for (const body of bodies) {
308
+ this.fullStateMap.set(body.id, { ...body });
309
+ }
310
+ }
311
+ /**
312
+ * Merge partial delta bodies into the full state map.
313
+ * Returns the merged (complete) body states for the bodies that were in the delta.
314
+ */
315
+ mergeDelta(bodies) {
316
+ const merged = [];
317
+ for (const body of bodies) {
318
+ const existing = this.fullStateMap.get(body.id);
319
+ if (existing) {
320
+ const mask = body.fieldMask;
321
+ if (mask !== undefined) {
322
+ if (mask & FIELD_POSITION)
323
+ existing.position = body.position;
324
+ if (mask & FIELD_ROTATION)
325
+ existing.rotation = body.rotation;
326
+ if (mask & FIELD_LIN_VEL)
327
+ existing.linVel = body.linVel;
328
+ if (mask & FIELD_ANG_VEL)
329
+ existing.angVel = body.angVel;
330
+ }
331
+ else {
332
+ // No fieldMask = full update
333
+ existing.position = body.position;
334
+ existing.rotation = body.rotation;
335
+ existing.linVel = body.linVel;
336
+ existing.angVel = body.angVel;
337
+ }
338
+ merged.push(existing);
339
+ }
340
+ else {
341
+ // New body — add to map
342
+ const newBody = { ...body };
343
+ delete newBody.fieldMask;
344
+ this.fullStateMap.set(body.id, newBody);
345
+ merged.push(newBody);
346
+ }
347
+ }
348
+ return merged;
349
+ }
350
+ handleMessage(message) {
351
+ switch (message.type) {
352
+ case MessageType.CLOCK_SYNC_RESPONSE:
353
+ this.clockSync.handleResponse(message);
354
+ break;
355
+ case MessageType.ROOM_CREATED:
356
+ this.createResolve?.();
357
+ this.createResolve = null;
358
+ break;
359
+ case MessageType.ROOM_JOINED:
360
+ this.roomId = message.roomId;
361
+ this.clientId = message.clientId;
362
+ this._simulationRunning = message.simulationRunning;
363
+ // Initialize body ID mapping
364
+ if (message.bodyIdMap) {
365
+ this.initBodyIdMap(message.bodyIdMap);
366
+ }
367
+ // Initialize full state from snapshot
368
+ this.initFullState(message.snapshot.bodies);
369
+ // Start input manager
370
+ this.inputManager.start((input) => this.sendClientInput(input), () => this.clockSync.getServerTick());
371
+ // Notify about existing constraints
372
+ if (message.constraints) {
373
+ for (const c of message.constraints) {
374
+ for (const cb of this.constraintAddedCallbacks) {
375
+ cb(c);
376
+ }
377
+ }
378
+ }
379
+ // Replay body descriptors for late joiners
380
+ if (message.bodies) {
381
+ for (const b of message.bodies) {
382
+ if (message.bodyIdMap && message.bodyIdMap[b.id] !== undefined) {
383
+ this.addBodyIdMapping(b.id, message.bodyIdMap[b.id]);
384
+ }
385
+ for (const cb of this.bodyAddedCallbacks) {
386
+ cb(b);
387
+ }
388
+ }
389
+ }
390
+ this.joinResolve?.(message.snapshot);
391
+ this.joinResolve = null;
392
+ break;
393
+ case MessageType.ROOM_STATE: {
394
+ // Merge partial delta into full state map
395
+ const mergedBodies = this.mergeDelta(message.bodies);
396
+ const snapshot = {
397
+ tick: message.tick,
398
+ timestamp: message.timestamp,
399
+ bodies: mergedBodies,
400
+ };
401
+ // Process through reconciler
402
+ this.reconciler.processServerState(snapshot);
403
+ // Notify listeners
404
+ for (const cb of this.stateUpdateCallbacks) {
405
+ cb(snapshot);
406
+ }
407
+ break;
408
+ }
409
+ case MessageType.ADD_BODY:
410
+ // Update body ID mapping
411
+ if (message.bodyIndex !== undefined) {
412
+ this.addBodyIdMapping(message.body.id, message.bodyIndex);
413
+ }
414
+ for (const cb of this.bodyAddedCallbacks) {
415
+ cb(message.body);
416
+ }
417
+ break;
418
+ case MessageType.REMOVE_BODY:
419
+ this.fullStateMap.delete(message.bodyId);
420
+ for (const cb of this.bodyRemovedCallbacks) {
421
+ cb(message.bodyId);
422
+ }
423
+ break;
424
+ case MessageType.SIMULATION_STARTED: {
425
+ this._simulationRunning = true;
426
+ this.reconciler.clear();
427
+ // Re-initialize body ID mapping if provided
428
+ const simMsg = message;
429
+ if (simMsg.bodyIdMap) {
430
+ this.initBodyIdMap(simMsg.bodyIdMap);
431
+ }
432
+ // Re-initialize full state from fresh snapshot
433
+ this.initFullState(message.snapshot.bodies);
434
+ // Notify about constraints included in reset
435
+ const simConstraints = message.constraints;
436
+ if (simConstraints) {
437
+ for (const c of simConstraints) {
438
+ for (const cb of this.constraintAddedCallbacks) {
439
+ cb(c);
440
+ }
441
+ }
442
+ }
443
+ // Replay body descriptors included in reset
444
+ const simBodies = message.bodies;
445
+ if (simBodies) {
446
+ for (const b of simBodies) {
447
+ for (const cb of this.bodyAddedCallbacks) {
448
+ cb(b);
449
+ }
450
+ }
451
+ }
452
+ const startSnapshot = message.snapshot;
453
+ for (const cb of this.simulationStartedCallbacks) {
454
+ cb(startSnapshot);
455
+ }
456
+ break;
457
+ }
458
+ case MessageType.COLLISION_EVENTS:
459
+ for (const cb of this.collisionEventsCallbacks) {
460
+ cb(message.events);
461
+ }
462
+ break;
463
+ case MessageType.ADD_CONSTRAINT:
464
+ for (const cb of this.constraintAddedCallbacks) {
465
+ cb(message.constraint);
466
+ }
467
+ break;
468
+ case MessageType.REMOVE_CONSTRAINT:
469
+ for (const cb of this.constraintRemovedCallbacks) {
470
+ cb(message.constraintId);
471
+ }
472
+ break;
473
+ case MessageType.ERROR:
474
+ console.error(`Server error: ${message.message}`);
475
+ break;
476
+ }
477
+ }
478
+ sendClientInput(input) {
479
+ this.reconciler.addPendingInput(input);
480
+ this.send({
481
+ type: MessageType.CLIENT_INPUT,
482
+ input,
483
+ });
484
+ }
485
+ send(message) {
486
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
487
+ const encoded = encodeMessage(message);
488
+ this._bytesSent += encoded.byteLength;
489
+ this.ws.send(encoded);
490
+ }
491
+ }
492
+ getReconciler() {
493
+ return this.reconciler;
494
+ }
495
+ getClockSync() {
496
+ return this.clockSync;
497
+ }
498
+ getInputManager() {
499
+ return this.inputManager;
500
+ }
501
+ getClientId() {
502
+ return this.clientId;
503
+ }
504
+ getRoomId() {
505
+ return this.roomId;
506
+ }
507
+ get bytesSent() {
508
+ return this._bytesSent;
509
+ }
510
+ get bytesReceived() {
511
+ return this._bytesReceived;
512
+ }
513
+ }
514
+ //# sourceMappingURL=sync-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-client.js","sourceRoot":"","sources":["../src/sync-client.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@rapierphysicsplugin/client",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc"
9
+ },
10
+ "dependencies": {
11
+ "@dimforge/rapier3d-compat": "^0.19.0",
12
+ "@rapierphysicsplugin/shared": "1.0.0"
13
+ },
14
+ "peerDependencies": {
15
+ "@babylonjs/core": ">=6.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@babylonjs/core": "^7.0.0",
19
+ "typescript": "^5.4.0"
20
+ }
21
+ }
@@ -0,0 +1,72 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { ClockSyncClient } from '../clock-sync.js';
3
+ import { MessageType } from '@rapierphysicsplugin/shared';
4
+
5
+ describe('ClockSyncClient', () => {
6
+ let clockSync: ClockSyncClient;
7
+
8
+ beforeEach(() => {
9
+ clockSync = new ClockSyncClient();
10
+ });
11
+
12
+ it('should start uncalibrated', () => {
13
+ expect(clockSync.isCalibrated).toBe(false);
14
+ expect(clockSync.getRTT()).toBe(0);
15
+ expect(clockSync.getClockOffset()).toBe(0);
16
+ });
17
+
18
+ it('should calculate RTT from response', () => {
19
+ const clientTimestamp = Date.now() - 50; // Simulate 50ms ago
20
+ clockSync.handleResponse({
21
+ type: MessageType.CLOCK_SYNC_RESPONSE,
22
+ clientTimestamp,
23
+ serverTimestamp: clientTimestamp + 25, // Server received ~25ms after client sent
24
+ });
25
+
26
+ const rtt = clockSync.getRTT();
27
+ expect(rtt).toBeGreaterThan(0);
28
+ expect(rtt).toBeLessThan(200); // Reasonable RTT
29
+ });
30
+
31
+ it('should become calibrated after 3 samples', () => {
32
+ for (let i = 0; i < 3; i++) {
33
+ const clientTimestamp = Date.now() - 50;
34
+ clockSync.handleResponse({
35
+ type: MessageType.CLOCK_SYNC_RESPONSE,
36
+ clientTimestamp,
37
+ serverTimestamp: clientTimestamp + 25,
38
+ });
39
+ }
40
+ expect(clockSync.isCalibrated).toBe(true);
41
+ });
42
+
43
+ it('should compute rolling average RTT', () => {
44
+ // Send several responses with known RTTs
45
+ for (let i = 0; i < 5; i++) {
46
+ const clientTimestamp = Date.now() - 100;
47
+ clockSync.handleResponse({
48
+ type: MessageType.CLOCK_SYNC_RESPONSE,
49
+ clientTimestamp,
50
+ serverTimestamp: clientTimestamp + 50,
51
+ });
52
+ }
53
+
54
+ const rtt = clockSync.getRTT();
55
+ // RTT should be around 100ms (now - clientTimestamp)
56
+ expect(rtt).toBeGreaterThan(50);
57
+ expect(rtt).toBeLessThan(300);
58
+ });
59
+
60
+ it('should get server time estimate', () => {
61
+ const now = Date.now();
62
+ clockSync.handleResponse({
63
+ type: MessageType.CLOCK_SYNC_RESPONSE,
64
+ clientTimestamp: now - 50,
65
+ serverTimestamp: now - 25,
66
+ });
67
+
68
+ const serverTime = clockSync.getServerTime();
69
+ // Server time should be close to current time
70
+ expect(Math.abs(serverTime - Date.now())).toBeLessThan(200);
71
+ });
72
+ });