@multitapio/multitap 0.0.2 → 0.0.4

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/channel.d.ts CHANGED
@@ -84,7 +84,6 @@ export declare class Channel implements AsyncTickLog {
84
84
  private _nextChannel;
85
85
  private _connectLoop;
86
86
  private _waitForIceGathering;
87
- private _listenForAnswer;
88
87
  private _handleDataChannel;
89
88
  private _handleMessage;
90
89
  private _dropChannel;
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
@@ -4141,19 +4141,25 @@ var Channel = class {
4141
4141
  this.peerConnection = pc;
4142
4142
  this.connectionGeneration++;
4143
4143
  const generation = this.connectionGeneration;
4144
+ let firstDataChannelResolver = null;
4145
+ const firstDataChannelPromise = new Promise((resolve) => {
4146
+ firstDataChannelResolver = resolve;
4147
+ });
4144
4148
  pc.ondatachannel = (event) => {
4145
4149
  if (generation === this.connectionGeneration) {
4146
- this._handleDataChannel(event.channel, generation);
4150
+ this._handleDataChannel(event.channel, generation, firstDataChannelResolver);
4151
+ firstDataChannelResolver = null;
4147
4152
  }
4148
4153
  };
4149
- pc.onconnectionstatechange = () => {
4150
- if (pc.connectionState === "failed" || pc.connectionState === "closed") {
4151
- if (generation === this.connectionGeneration) {
4152
- this._setConnected(false);
4153
- this._cleanupPeerConnection();
4154
- }
4154
+ const handleConnectionState = () => {
4155
+ if (generation !== this.connectionGeneration) return;
4156
+ const state = pc.connectionState;
4157
+ if (state === "failed" || state === "closed") {
4158
+ this._setConnected(false);
4159
+ this._cleanupPeerConnection();
4155
4160
  }
4156
4161
  };
4162
+ pc.addEventListener("connectionstatechange", handleConnectionState);
4157
4163
  pc.createDataChannel("negotiation");
4158
4164
  const offer = await pc.createOffer();
4159
4165
  await pc.setLocalDescription(offer);
@@ -4163,9 +4169,6 @@ var Channel = class {
4163
4169
  throw new Error("Failed to get local description");
4164
4170
  }
4165
4171
  const pubKeyHex = bytesToHex2(this.publicKey);
4166
- const sseURL = `${base}/rtc/events?session=${sessionParam}&pubkey=${pubKeyHex}`;
4167
- const sseController = new AbortController();
4168
- const ssePromise = this._listenForAnswer(sseURL, sseController.signal);
4169
4172
  const offerURL = `${base}/rtc/offer?session=${sessionParam}&from=${pubKeyHex}&to=relay`;
4170
4173
  const offerResponse = await fetch(offerURL, {
4171
4174
  method: "POST",
@@ -4176,30 +4179,32 @@ var Channel = class {
4176
4179
  })
4177
4180
  });
4178
4181
  if (!offerResponse.ok) {
4179
- sseController.abort();
4180
4182
  throw new Error(`Offer rejected: ${offerResponse.status}`);
4181
4183
  }
4182
- const timeoutPromise = new Promise((_, reject) => {
4183
- setTimeout(() => reject(new Error("SSE timeout")), this.connectionTimeoutMs);
4184
- });
4185
- const answerSDP = await Promise.race([ssePromise, timeoutPromise]);
4186
- sseController.abort();
4184
+ const answerData = await offerResponse.json();
4187
4185
  await pc.setRemoteDescription({
4188
4186
  type: "answer",
4189
- sdp: answerSDP
4187
+ sdp: answerData.sdp
4190
4188
  });
4191
- this.stats.reconnections++;
4192
- this._setConnected(true);
4193
4189
  this.dataChannels = [];
4194
4190
  this.replayChannels.clear();
4195
4191
  this.roundRobinIndex = 0;
4192
+ const dataChannelTimeout = new Promise((_, reject) => {
4193
+ setTimeout(() => reject(new Error("DataChannel timeout")), this.connectionTimeoutMs);
4194
+ });
4195
+ await Promise.race([firstDataChannelPromise, dataChannelTimeout]);
4196
+ this.stats.reconnections++;
4197
+ this._setConnected(true);
4196
4198
  consecutiveFailures = 0;
4197
4199
  await new Promise((resolve) => {
4198
- pc.onconnectionstatechange = () => {
4199
- if (pc.connectionState === "failed" || pc.connectionState === "closed" || pc.connectionState === "disconnected") {
4200
+ const checkDisconnect = () => {
4201
+ const state = pc.connectionState;
4202
+ if (state === "failed" || state === "closed" || state === "disconnected") {
4203
+ pc.removeEventListener("connectionstatechange", checkDisconnect);
4200
4204
  resolve();
4201
4205
  }
4202
4206
  };
4207
+ pc.addEventListener("connectionstatechange", checkDisconnect);
4203
4208
  });
4204
4209
  } catch (e) {
4205
4210
  if (this.debug) {
@@ -4217,66 +4222,26 @@ var Channel = class {
4217
4222
  console.log("connect loop exited");
4218
4223
  }
4219
4224
  }
4220
- // Wait for ICE gathering to complete
4225
+ // Wait for ICE gathering to complete (with timeout)
4221
4226
  async _waitForIceGathering(pc) {
4222
4227
  if (pc.iceGatheringState === "complete") {
4223
4228
  return;
4224
4229
  }
4225
4230
  return new Promise((resolve) => {
4226
- pc.onicegatheringstatechange = () => {
4231
+ const checkState = () => {
4227
4232
  if (pc.iceGatheringState === "complete") {
4233
+ pc.removeEventListener("icegatheringstatechange", checkState);
4228
4234
  resolve();
4229
4235
  }
4230
4236
  };
4237
+ pc.addEventListener("icegatheringstatechange", checkState);
4238
+ setTimeout(() => {
4239
+ pc.removeEventListener("icegatheringstatechange", checkState);
4240
+ resolve();
4241
+ }, 5e3);
4231
4242
  });
4232
4243
  }
4233
- // Listen for answer from SSE
4234
- async _listenForAnswer(url, signal) {
4235
- const response = await fetch(url, {
4236
- headers: { Accept: "text/event-stream", "Cache-Control": "no-cache" },
4237
- signal
4238
- });
4239
- if (!response.ok) {
4240
- throw new Error(`SSE connection failed: ${response.status}`);
4241
- }
4242
- const reader = response.body?.getReader();
4243
- if (!reader) {
4244
- throw new Error("SSE response has no body");
4245
- }
4246
- const decoder = new TextDecoder();
4247
- let buffer2 = "";
4248
- let eventType = "";
4249
- let eventData = "";
4250
- try {
4251
- while (true) {
4252
- const { value, done } = await reader.read();
4253
- if (done) break;
4254
- buffer2 += decoder.decode(value, { stream: true });
4255
- const lines = buffer2.split("\n");
4256
- buffer2 = lines.pop() ?? "";
4257
- for (const line of lines) {
4258
- if (line.startsWith("event:")) {
4259
- eventType = line.slice(6).trim();
4260
- } else if (line.startsWith("data:")) {
4261
- eventData = line.slice(5).trim();
4262
- } else if (line === "" && eventData) {
4263
- if (eventType === "answer") {
4264
- const answerMsg = JSON.parse(eventData);
4265
- if (answerMsg.from === "relay" && answerMsg.sdp) {
4266
- return answerMsg.sdp;
4267
- }
4268
- }
4269
- eventType = "";
4270
- eventData = "";
4271
- }
4272
- }
4273
- }
4274
- } finally {
4275
- reader.releaseLock();
4276
- }
4277
- throw new Error("SSE stream closed without receiving answer");
4278
- }
4279
- _handleDataChannel(dc, generation) {
4244
+ _handleDataChannel(dc, generation, onFirstOpen) {
4280
4245
  const handle = {
4281
4246
  dc,
4282
4247
  index: this.dataChannels.length,
@@ -4287,6 +4252,9 @@ var Channel = class {
4287
4252
  dc.onopen = () => {
4288
4253
  if (generation === this.connectionGeneration) {
4289
4254
  this.dataChannels.push(handle);
4255
+ if (onFirstOpen) {
4256
+ onFirstOpen();
4257
+ }
4290
4258
  if (this.outbox.length > 0) {
4291
4259
  this._flushOutbox().catch(warnUnexpected);
4292
4260
  }
package/dist/lib.js CHANGED
@@ -4278,19 +4278,25 @@ var Channel = class {
4278
4278
  this.peerConnection = pc;
4279
4279
  this.connectionGeneration++;
4280
4280
  const generation = this.connectionGeneration;
4281
+ let firstDataChannelResolver = null;
4282
+ const firstDataChannelPromise = new Promise((resolve) => {
4283
+ firstDataChannelResolver = resolve;
4284
+ });
4281
4285
  pc.ondatachannel = (event) => {
4282
4286
  if (generation === this.connectionGeneration) {
4283
- this._handleDataChannel(event.channel, generation);
4287
+ this._handleDataChannel(event.channel, generation, firstDataChannelResolver);
4288
+ firstDataChannelResolver = null;
4284
4289
  }
4285
4290
  };
4286
- pc.onconnectionstatechange = () => {
4287
- if (pc.connectionState === "failed" || pc.connectionState === "closed") {
4288
- if (generation === this.connectionGeneration) {
4289
- this._setConnected(false);
4290
- this._cleanupPeerConnection();
4291
- }
4291
+ const handleConnectionState = () => {
4292
+ if (generation !== this.connectionGeneration) return;
4293
+ const state = pc.connectionState;
4294
+ if (state === "failed" || state === "closed") {
4295
+ this._setConnected(false);
4296
+ this._cleanupPeerConnection();
4292
4297
  }
4293
4298
  };
4299
+ pc.addEventListener("connectionstatechange", handleConnectionState);
4294
4300
  pc.createDataChannel("negotiation");
4295
4301
  const offer = await pc.createOffer();
4296
4302
  await pc.setLocalDescription(offer);
@@ -4300,9 +4306,6 @@ var Channel = class {
4300
4306
  throw new Error("Failed to get local description");
4301
4307
  }
4302
4308
  const pubKeyHex = bytesToHex2(this.publicKey);
4303
- const sseURL = `${base}/rtc/events?session=${sessionParam}&pubkey=${pubKeyHex}`;
4304
- const sseController = new AbortController();
4305
- const ssePromise = this._listenForAnswer(sseURL, sseController.signal);
4306
4309
  const offerURL = `${base}/rtc/offer?session=${sessionParam}&from=${pubKeyHex}&to=relay`;
4307
4310
  const offerResponse = await fetch(offerURL, {
4308
4311
  method: "POST",
@@ -4313,30 +4316,32 @@ var Channel = class {
4313
4316
  })
4314
4317
  });
4315
4318
  if (!offerResponse.ok) {
4316
- sseController.abort();
4317
4319
  throw new Error(`Offer rejected: ${offerResponse.status}`);
4318
4320
  }
4319
- const timeoutPromise = new Promise((_, reject) => {
4320
- setTimeout(() => reject(new Error("SSE timeout")), this.connectionTimeoutMs);
4321
- });
4322
- const answerSDP = await Promise.race([ssePromise, timeoutPromise]);
4323
- sseController.abort();
4321
+ const answerData = await offerResponse.json();
4324
4322
  await pc.setRemoteDescription({
4325
4323
  type: "answer",
4326
- sdp: answerSDP
4324
+ sdp: answerData.sdp
4327
4325
  });
4328
- this.stats.reconnections++;
4329
- this._setConnected(true);
4330
4326
  this.dataChannels = [];
4331
4327
  this.replayChannels.clear();
4332
4328
  this.roundRobinIndex = 0;
4329
+ const dataChannelTimeout = new Promise((_, reject) => {
4330
+ setTimeout(() => reject(new Error("DataChannel timeout")), this.connectionTimeoutMs);
4331
+ });
4332
+ await Promise.race([firstDataChannelPromise, dataChannelTimeout]);
4333
+ this.stats.reconnections++;
4334
+ this._setConnected(true);
4333
4335
  consecutiveFailures = 0;
4334
4336
  await new Promise((resolve) => {
4335
- pc.onconnectionstatechange = () => {
4336
- if (pc.connectionState === "failed" || pc.connectionState === "closed" || pc.connectionState === "disconnected") {
4337
+ const checkDisconnect = () => {
4338
+ const state = pc.connectionState;
4339
+ if (state === "failed" || state === "closed" || state === "disconnected") {
4340
+ pc.removeEventListener("connectionstatechange", checkDisconnect);
4337
4341
  resolve();
4338
4342
  }
4339
4343
  };
4344
+ pc.addEventListener("connectionstatechange", checkDisconnect);
4340
4345
  });
4341
4346
  } catch (e) {
4342
4347
  if (this.debug) {
@@ -4354,66 +4359,26 @@ var Channel = class {
4354
4359
  console.log("connect loop exited");
4355
4360
  }
4356
4361
  }
4357
- // Wait for ICE gathering to complete
4362
+ // Wait for ICE gathering to complete (with timeout)
4358
4363
  async _waitForIceGathering(pc) {
4359
4364
  if (pc.iceGatheringState === "complete") {
4360
4365
  return;
4361
4366
  }
4362
4367
  return new Promise((resolve) => {
4363
- pc.onicegatheringstatechange = () => {
4368
+ const checkState = () => {
4364
4369
  if (pc.iceGatheringState === "complete") {
4370
+ pc.removeEventListener("icegatheringstatechange", checkState);
4365
4371
  resolve();
4366
4372
  }
4367
4373
  };
4374
+ pc.addEventListener("icegatheringstatechange", checkState);
4375
+ setTimeout(() => {
4376
+ pc.removeEventListener("icegatheringstatechange", checkState);
4377
+ resolve();
4378
+ }, 5e3);
4368
4379
  });
4369
4380
  }
4370
- // Listen for answer from SSE
4371
- async _listenForAnswer(url, signal) {
4372
- const response = await fetch(url, {
4373
- headers: { Accept: "text/event-stream", "Cache-Control": "no-cache" },
4374
- signal
4375
- });
4376
- if (!response.ok) {
4377
- throw new Error(`SSE connection failed: ${response.status}`);
4378
- }
4379
- const reader = response.body?.getReader();
4380
- if (!reader) {
4381
- throw new Error("SSE response has no body");
4382
- }
4383
- const decoder = new TextDecoder();
4384
- let buffer2 = "";
4385
- let eventType = "";
4386
- let eventData = "";
4387
- try {
4388
- while (true) {
4389
- const { value, done } = await reader.read();
4390
- if (done) break;
4391
- buffer2 += decoder.decode(value, { stream: true });
4392
- const lines = buffer2.split("\n");
4393
- buffer2 = lines.pop() ?? "";
4394
- for (const line of lines) {
4395
- if (line.startsWith("event:")) {
4396
- eventType = line.slice(6).trim();
4397
- } else if (line.startsWith("data:")) {
4398
- eventData = line.slice(5).trim();
4399
- } else if (line === "" && eventData) {
4400
- if (eventType === "answer") {
4401
- const answerMsg = JSON.parse(eventData);
4402
- if (answerMsg.from === "relay" && answerMsg.sdp) {
4403
- return answerMsg.sdp;
4404
- }
4405
- }
4406
- eventType = "";
4407
- eventData = "";
4408
- }
4409
- }
4410
- }
4411
- } finally {
4412
- reader.releaseLock();
4413
- }
4414
- throw new Error("SSE stream closed without receiving answer");
4415
- }
4416
- _handleDataChannel(dc, generation) {
4381
+ _handleDataChannel(dc, generation, onFirstOpen) {
4417
4382
  const handle = {
4418
4383
  dc,
4419
4384
  index: this.dataChannels.length,
@@ -4424,6 +4389,9 @@ var Channel = class {
4424
4389
  dc.onopen = () => {
4425
4390
  if (generation === this.connectionGeneration) {
4426
4391
  this.dataChannels.push(handle);
4392
+ if (onFirstOpen) {
4393
+ onFirstOpen();
4394
+ }
4427
4395
  if (this.outbox.length > 0) {
4428
4396
  this._flushOutbox().catch(warnUnexpected);
4429
4397
  }
@@ -84,7 +84,6 @@ export declare class Channel implements AsyncTickLog {
84
84
  private _nextChannel;
85
85
  private _connectLoop;
86
86
  private _waitForIceGathering;
87
- private _listenForAnswer;
88
87
  private _handleDataChannel;
89
88
  private _handleMessage;
90
89
  private _dropChannel;
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@multitapio/multitap",
3
3
  "type": "module",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "description": "Rollback networking SDK for fast-paced multiplayer games",
6
6
  "main": "./dist/lib.js",
7
7
  "types": "./dist/lib.d.ts",
@@ -1,3 +0,0 @@
1
- declare const _default: new () => Worker;
2
- export default _default;
3
- //# sourceMappingURL=channel.worker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"channel.worker.d.ts","sourceRoot":"","sources":["../../src/channel.worker.ts"],"names":[],"mappings":"wBAMkC,UAAU,MAAM;AAAlD,wBAAmD"}
@@ -1,3 +0,0 @@
1
- declare const _default: new () => Worker;
2
- export default _default;
3
- //# sourceMappingURL=channel.worker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"channel.worker.d.ts","sourceRoot":"","sources":["../../src/channel.worker.ts"],"names":[],"mappings":"wBAMkC,UAAU,MAAM;AAAlD,wBAAmD"}
@@ -1,79 +0,0 @@
1
- import type { InputData, TickMessage } from './messages';
2
- import { InputGraph, type AsyncTickLog, type GetTicksAfterOptions, type Participant, type PayloadPredictor, type TickNode, type TickPrimitive } from './input-graph';
3
- export type StateListener = (connected: boolean) => void;
4
- export type UnsubscribeFn = () => void;
5
- export interface WebRTCChannelConfig {
6
- /** multitap:// connection URL (will be base64-encoded for transport) */
7
- connectionURL: string;
8
- privateKey?: Uint8Array;
9
- relayPubKey?: Uint8Array | undefined | null;
10
- inputPayloadPredictor?: PayloadPredictor | null;
11
- debug?: boolean | undefined;
12
- autoConnect?: boolean | undefined;
13
- connectionTimeoutMs?: number | undefined;
14
- logSyncTicks?: boolean | undefined;
15
- }
16
- export declare class WebRTCChannel implements AsyncTickLog {
17
- readonly connectionURL: string;
18
- readonly connectionTimeoutMs: number;
19
- private privateKey;
20
- private publicKey;
21
- private genesisHash;
22
- private sessionConfig;
23
- private pc;
24
- private dataChannels;
25
- private replayChannels;
26
- private roundRobinIndex;
27
- private connectionGeneration;
28
- private connected;
29
- private stopped;
30
- private debug;
31
- private logSyncTicks;
32
- private outbox;
33
- private stateListeners;
34
- private flushingOutbox;
35
- private tickRate;
36
- inputGraph: InputGraph;
37
- private tickDeadlineWants;
38
- private tickDeadlineTimer;
39
- private tickDeadlineGrace;
40
- private stats;
41
- constructor(config: WebRTCChannelConfig);
42
- connect(): Promise<void>;
43
- getPublicKey(): Promise<Uint8Array<ArrayBufferLike>>;
44
- getGenesisHash(): Promise<Uint8Array<ArrayBufferLike>>;
45
- onStateChange(fn: StateListener): UnsubscribeFn;
46
- getStats(): {
47
- activeChannels: number;
48
- totalChannels: number;
49
- messagesRecv: number;
50
- messagesSent: number;
51
- reconnections: number;
52
- };
53
- getTickRate(): Promise<number>;
54
- getParticipantSlots(tick: number): Promise<Participant[]>;
55
- getSyncHead(): Promise<TickNode>;
56
- getPredictedHead(): Promise<TickNode>;
57
- addSyncTick(msg: TickMessage): Promise<void>;
58
- addOptimisticInput(input: InputData, preVerifiedSigner?: Uint8Array): Promise<void>;
59
- getPredictionCount(): Promise<number>;
60
- getTicksAfter(nodeId: string | null, options?: GetTicksAfterOptions): Promise<TickPrimitive[]>;
61
- setOnParticipantJoined(fn: (participant: Participant) => void): Promise<void>;
62
- expose(port: MessagePort): Promise<void>;
63
- close(): Promise<void>;
64
- private _setConnected;
65
- private _generateNullInput;
66
- private _send;
67
- sendSignedInput(payload: Uint8Array, targetTick?: number): Promise<Uint8Array>;
68
- private _nextChannel;
69
- private _connectLoop;
70
- private _addDataChannel;
71
- private _removeChannel;
72
- private _handleMessage;
73
- private _maybeResetDeadline;
74
- private _resetDeadline;
75
- private _onTickDeadlineExceeded;
76
- private _flushOutbox;
77
- private _cleanupConnection;
78
- }
79
- //# sourceMappingURL=webrtc-channel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webrtc-channel.d.ts","sourceRoot":"","sources":["../../src/webrtc-channel.ts"],"names":[],"mappings":"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"}
@@ -1,79 +0,0 @@
1
- import type { InputData, TickMessage } from './messages';
2
- import { InputGraph, type AsyncTickLog, type GetTicksAfterOptions, type Participant, type PayloadPredictor, type TickNode, type TickPrimitive } from './input-graph';
3
- export type StateListener = (connected: boolean) => void;
4
- export type UnsubscribeFn = () => void;
5
- export interface WebRTCChannelConfig {
6
- /** multitap:// connection URL (will be base64-encoded for transport) */
7
- connectionURL: string;
8
- privateKey?: Uint8Array;
9
- relayPubKey?: Uint8Array | undefined | null;
10
- inputPayloadPredictor?: PayloadPredictor | null;
11
- debug?: boolean | undefined;
12
- autoConnect?: boolean | undefined;
13
- connectionTimeoutMs?: number | undefined;
14
- logSyncTicks?: boolean | undefined;
15
- }
16
- export declare class WebRTCChannel implements AsyncTickLog {
17
- readonly connectionURL: string;
18
- readonly connectionTimeoutMs: number;
19
- private privateKey;
20
- private publicKey;
21
- private genesisHash;
22
- private sessionConfig;
23
- private pc;
24
- private dataChannels;
25
- private replayChannels;
26
- private roundRobinIndex;
27
- private connectionGeneration;
28
- private connected;
29
- private stopped;
30
- private debug;
31
- private logSyncTicks;
32
- private outbox;
33
- private stateListeners;
34
- private flushingOutbox;
35
- private tickRate;
36
- inputGraph: InputGraph;
37
- private tickDeadlineWants;
38
- private tickDeadlineTimer;
39
- private tickDeadlineGrace;
40
- private stats;
41
- constructor(config: WebRTCChannelConfig);
42
- connect(): Promise<void>;
43
- getPublicKey(): Promise<Uint8Array<ArrayBufferLike>>;
44
- getGenesisHash(): Promise<Uint8Array<ArrayBufferLike>>;
45
- onStateChange(fn: StateListener): UnsubscribeFn;
46
- getStats(): {
47
- activeChannels: number;
48
- totalChannels: number;
49
- messagesRecv: number;
50
- messagesSent: number;
51
- reconnections: number;
52
- };
53
- getTickRate(): Promise<number>;
54
- getParticipantSlots(tick: number): Promise<Participant[]>;
55
- getSyncHead(): Promise<TickNode>;
56
- getPredictedHead(): Promise<TickNode>;
57
- addSyncTick(msg: TickMessage): Promise<void>;
58
- addOptimisticInput(input: InputData, preVerifiedSigner?: Uint8Array): Promise<void>;
59
- getPredictionCount(): Promise<number>;
60
- getTicksAfter(nodeId: string | null, options?: GetTicksAfterOptions): Promise<TickPrimitive[]>;
61
- setOnParticipantJoined(fn: (participant: Participant) => void): Promise<void>;
62
- expose(port: MessagePort): Promise<void>;
63
- close(): Promise<void>;
64
- private _setConnected;
65
- private _generateNullInput;
66
- private _send;
67
- sendSignedInput(payload: Uint8Array, targetTick?: number): Promise<Uint8Array>;
68
- private _nextChannel;
69
- private _connectLoop;
70
- private _addDataChannel;
71
- private _removeChannel;
72
- private _handleMessage;
73
- private _maybeResetDeadline;
74
- private _resetDeadline;
75
- private _onTickDeadlineExceeded;
76
- private _flushOutbox;
77
- private _cleanupConnection;
78
- }
79
- //# sourceMappingURL=webrtc-channel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webrtc-channel.d.ts","sourceRoot":"","sources":["../../src/webrtc-channel.ts"],"names":[],"mappings":"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"}