openrtc-netcode 1.0.0 → 2.0.0-rc.1

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/README.md CHANGED
@@ -6,23 +6,31 @@ and exposes reliable typed messages, lightweight replicated state, networked
6
6
  objects, and browser voice-chat signaling.
7
7
 
8
8
  Gameplay payloads are sent over OpenRTC peer data paths only: Iroh
9
- relay/direct, WebRTC DataChannel upgrades, and MoQ routes when enabled. Firebase
10
- and Firestore remain part of OpenRTC's control plane for identity, discovery,
11
- rooms, tickets, and browser signaling metadata; `openrtc-netcode` does not use
12
- Firestore as a state or message relay.
9
+ relay/direct, WebRTC DataChannel upgrades, and MoQ routes when enabled. Live
10
+ membership and signaling use the OpenRTC coordination gateway; neither core
11
+ netcode nor its payload path uses Firebase, Firestore, or RTDB.
13
12
 
14
13
  `preferredPayloadTransports` filters OpenRTC's typed application-readiness
15
- query; it does not request promotion. When netcode creates the runtime,
16
- `transports` and `transportPriority` are forwarded to `OpenRTC(...)` at
17
- construction. An injected runtime must be configured by its owner. OpenRTC owns
18
- optional transport promotion and recovery, while netcode only observes later
19
- route events and never requests or suppresses upgrades.
14
+ query; it does not request promotion. OpenRTC owns optional transport promotion
15
+ and recovery, while netcode only observes route events. Netcode consumes one
16
+ already-activated room handle, so it never retains an unused user or space
17
+ avenue.
20
18
 
21
19
  ```ts
20
+ import { OpenRTC } from 'openrtc';
22
21
  import { createNetcode } from 'openrtc-netcode';
23
22
 
24
- const netcode = createNetcode({ apiKey: 'pk_live_...' });
25
- await netcode.createLobby({ id: 'duel-room' });
23
+ const rtc = OpenRTC({
24
+ apiKey: 'pk_live_...',
25
+ transports: { webrtc: true },
26
+ });
27
+ const room = await rtc.rooms.join('duel-room', {
28
+ access: 'capability',
29
+ membership: 'ephemeral',
30
+ maxPeers: 4,
31
+ });
32
+ const netcode = createNetcode({ room });
33
+ await netcode.joinLobby('duel-room');
26
34
 
27
35
  netcode.onMessage('chat', (message) => {
28
36
  console.log(message.from, message.payload);
package/dist/client.d.ts CHANGED
@@ -5,7 +5,6 @@ import type { CreateLobbyOptions, JoinLobbyOptions, NetcodeClient as NetcodeClie
5
5
  export declare class OpenRtcNetcodeClient implements NetcodeClientInterface {
6
6
  private readonly options;
7
7
  private runtime;
8
- private ownsRuntime;
9
8
  private localPeerId;
10
9
  private currentLobby;
11
10
  private currentRoomId;
@@ -32,6 +31,7 @@ export declare class OpenRtcNetcodeClient implements NetcodeClientInterface {
32
31
  private readonly introPeerIds;
33
32
  private readonly seenEnvelopeIds;
34
33
  private readonly seenEnvelopeOrder;
34
+ private readonly latestStateQueues;
35
35
  private readonly stateStore;
36
36
  private readonly objectStore;
37
37
  private readonly voiceController;
@@ -83,6 +83,7 @@ export declare class OpenRtcNetcodeClient implements NetcodeClientInterface {
83
83
  private refreshPeerPayloadState;
84
84
  private stopPeerPingLoop;
85
85
  private broadcastEnvelope;
86
+ private broadcastLatestState;
86
87
  private sendEnvelope;
87
88
  private sendDirectEnvelope;
88
89
  private warnDirectSendFailure;
package/dist/client.js CHANGED
@@ -1,9 +1,10 @@
1
- import { OpenRTC } from 'openrtc';
2
1
  import { TypedEmitter } from './events.js';
3
2
  import { decodeEnvelope, encodeEnvelope, isRecord, NETCODE_PROTOCOL, NETCODE_PROTOCOL_VERSION, } from './protocol.js';
4
3
  import { isNetcodeObjectState, ReplicatedObjectStore } from './objects.js';
5
4
  import { ReplicatedState } from './state.js';
6
5
  import { NetcodeVoiceController } from './voice.js';
6
+ import { runtimeFromRoom } from './roomRuntime.js';
7
+ import { LatestStateQueue } from './latestState.js';
7
8
  const DEFAULT_MAX_PEERS = 8;
8
9
  const NETCODE_CHANNEL_ID = 'openrtc-netcode/v1';
9
10
  const PING_INTERVAL_MS = 2000;
@@ -16,7 +17,6 @@ export class OpenRtcNetcodeClient {
16
17
  constructor(options = {}) {
17
18
  this.options = options;
18
19
  this.runtime = null;
19
- this.ownsRuntime = false;
20
20
  this.localPeerId = null;
21
21
  this.currentLobby = null;
22
22
  this.currentRoomId = null;
@@ -43,8 +43,9 @@ export class OpenRtcNetcodeClient {
43
43
  this.introPeerIds = new Set();
44
44
  this.seenEnvelopeIds = new Set();
45
45
  this.seenEnvelopeOrder = [];
46
- this.stateStore = new ReplicatedState((options) => this.resolveStateOwner(options), (key, value, owner) => this.broadcastEnvelope('state.patch', { key, value, owner }));
47
- this.objectStore = new ReplicatedObjectStore(() => this.localPeerId, (object) => this.broadcastEnvelope('object.upsert', { object }), (id) => this.broadcastEnvelope('object.remove', { id }));
46
+ this.latestStateQueues = new Map();
47
+ this.stateStore = new ReplicatedState((options) => this.resolveStateOwner(options), (key, value, owner) => this.broadcastLatestState(`state:${key}`, 'state.patch', { key, value, owner }));
48
+ this.objectStore = new ReplicatedObjectStore(() => this.localPeerId, (object) => this.broadcastLatestState(`object:${object.id}`, 'object.upsert', { object }), (id) => this.broadcastEnvelope('object.remove', { id }));
48
49
  this.voiceController = new NetcodeVoiceController(() => this.localPeerId, () => this.peers, shouldInitiateConnection, (peerId, signal) => this.sendEnvelope(peerId, 'voice.signal', { signal }));
49
50
  }
50
51
  get peerId() {
@@ -74,23 +75,10 @@ export class OpenRtcNetcodeClient {
74
75
  }
75
76
  this.started = true;
76
77
  this.stopped = false;
77
- this.runtime = this.options.runtime ?? OpenRTC({
78
- apiKey: this.options.apiKey,
79
- projectId: this.options.projectId,
80
- authMode: this.options.authMode,
81
- discoveryMode: this.options.discoveryMode,
82
- allowAnonymousHostedDefaults: this.options.allowAnonymousHostedDefaults,
83
- space: this.options.space,
84
- spaceKey: this.options.spaceKey,
85
- spaceTokenProvider: this.options.spaceTokenProvider,
86
- storagePrefix: this.options.storagePrefix,
87
- nodeIdPersistence: this.options.nodeIdPersistence,
88
- transports: this.options.transports,
89
- transportPriority: this.options.transportPriority,
90
- strictMode: this.options.strictMode,
91
- turnCredentialsProvider: this.options.turnCredentialsProvider,
92
- });
93
- this.ownsRuntime = !this.options.runtime;
78
+ if (!this.options.runtime && !this.options.room) {
79
+ throw new Error('openrtc-netcode requires an activated OpenRTC 2.0 room adapter or an explicit openrtc/runtime client.');
80
+ }
81
+ this.runtime = this.options.runtime ?? runtimeFromRoom(this.options.room);
94
82
  await callOptional(this.runtime, 'initialize');
95
83
  await callOptional(this.runtime, 'start');
96
84
  this.localPeerId = await this.runtime.getNodeId();
@@ -123,15 +111,13 @@ export class OpenRtcNetcodeClient {
123
111
  this.peerStatsById.clear();
124
112
  this.seenEnvelopeIds.clear();
125
113
  this.seenEnvelopeOrder.length = 0;
114
+ this.latestStateQueues.clear();
126
115
  this.stopPeerPingLoop();
127
116
  this.peersById.clear();
128
117
  this.objectStore.clear();
129
118
  await this.voiceController.stop();
130
119
  this.emitter.clear();
131
120
  this.messageListeners.clear();
132
- if (this.ownsRuntime) {
133
- await callOptional(this.runtime, 'stop');
134
- }
135
121
  this.runtime = null;
136
122
  this.started = false;
137
123
  }
@@ -237,6 +223,7 @@ export class OpenRtcNetcodeClient {
237
223
  this.peerStatsById.clear();
238
224
  this.seenEnvelopeIds.clear();
239
225
  this.seenEnvelopeOrder.length = 0;
226
+ this.latestStateQueues.clear();
240
227
  this.objectStore.clear();
241
228
  await this.voiceController.stop();
242
229
  if (runtime && roomId) {
@@ -326,6 +313,14 @@ export class OpenRtcNetcodeClient {
326
313
  if (!this.runtime || !this.localPeerId) {
327
314
  return;
328
315
  }
316
+ // An OpenRTC 2.0 room capability is the sole owner of its peer
317
+ // lifecycle. Calling connectByTicket here races that owner and can
318
+ // restart reciprocal application-key agreement on an already-admitted
319
+ // physical connection. Explicit legacy/test runtimes retain the
320
+ // deterministic mesh dial below.
321
+ if (this.runtime.managedConnectionLifecycle) {
322
+ return;
323
+ }
329
324
  const maxPeers = this.options.maxPeers ?? DEFAULT_MAX_PEERS;
330
325
  for (const peer of this.peersById.values()) {
331
326
  if (this.connectionsByPeer.size >= maxPeers) {
@@ -684,6 +679,14 @@ export class OpenRtcNetcodeClient {
684
679
  const sends = Array.from(this.connectionsByPeer.keys()).map((peerId) => this.sendDirectEnvelope(peerId, envelope));
685
680
  await Promise.all(sends);
686
681
  }
682
+ broadcastLatestState(key, kind, body) {
683
+ let queue = this.latestStateQueues.get(key);
684
+ if (!queue) {
685
+ queue = new LatestStateQueue((state) => this.broadcastEnvelope(state.kind, state.body));
686
+ this.latestStateQueues.set(key, queue);
687
+ }
688
+ return queue.push({ kind, body });
689
+ }
687
690
  async sendEnvelope(peerId, kind, body) {
688
691
  const envelope = this.createEnvelope(kind, body, peerId);
689
692
  if (this.fallbackChannel) {
@@ -969,10 +972,7 @@ export class OpenRtcNetcodeClient {
969
972
  return this.connectionsByPeer.get(peerId) ?? null;
970
973
  }
971
974
  payloadReadinessOptions() {
972
- const preferredTransports = this.options.preferredPayloadTransports
973
- ?? (this.ownsRuntime
974
- ? derivePreferredPayloadTransports(this.options.transports, this.options.transportPriority)
975
- : []);
975
+ const preferredTransports = this.options.preferredPayloadTransports ?? [];
976
976
  if (preferredTransports.length === 0) {
977
977
  return {};
978
978
  }
@@ -1127,21 +1127,6 @@ function isRoomAdmissionTransientError(error) {
1127
1127
  return isRoomNotFoundError(error)
1128
1128
  || /permission[_ -]?denied|permission denied|forbidden|code["']?\s*:\s*403|status["']?\s*:\s*["']?permission_denied/i.test(text);
1129
1129
  }
1130
- function derivePreferredPayloadTransports(transports, transportPriority) {
1131
- const configuredPriority = (transportPriority ?? [])
1132
- .filter((transport) => UPGRADED_PAYLOAD_TRANSPORTS.has(transport));
1133
- if (configuredPriority.length > 0) {
1134
- return [...new Set(configuredPriority)];
1135
- }
1136
- const preferred = [];
1137
- if (transports?.webrtc) {
1138
- preferred.push('webrtc-lan', 'webrtc');
1139
- }
1140
- if (transports?.moq) {
1141
- preferred.push('moq');
1142
- }
1143
- return preferred;
1144
- }
1145
1130
  function delay(ms) {
1146
1131
  return new Promise((resolve) => setTimeout(resolve, ms));
1147
1132
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { OpenRtcNetcodeClient, createNetcode, shouldInitiateConnection, } from './client.js';
2
+ export { runtimeFromRoom } from './roomRuntime.js';
2
3
  export { ReplicatedObjectStore } from './objects.js';
3
4
  export { NETCODE_PROTOCOL, NETCODE_PROTOCOL_VERSION, decodeEnvelope, encodeEnvelope, isEnvelopeKind, } from './protocol.js';
4
5
  export type { HelloBody, MetadataBody, NetcodeEnvelope, NetcodeEnvelopeKind, ObjectRemoveBody, ObjectSnapshotBody, ObjectUpsertBody, StatePatchBody, StateSnapshotBody, UserMessageBody, VoiceSignalBody, } from './protocol.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { OpenRtcNetcodeClient, createNetcode, shouldInitiateConnection, } from './client.js';
2
+ export { runtimeFromRoom } from './roomRuntime.js';
2
3
  export { ReplicatedObjectStore } from './objects.js';
3
4
  export { NETCODE_PROTOCOL, NETCODE_PROTOCOL_VERSION, decodeEnvelope, encodeEnvelope, isEnvelopeKind, } from './protocol.js';
@@ -0,0 +1,9 @@
1
+ /** Coalesces only queued values; the in-flight state is allowed to finish. */
2
+ export declare class LatestStateQueue<T> {
3
+ private readonly transmit;
4
+ private pending;
5
+ private running;
6
+ constructor(transmit: (value: T) => Promise<void>);
7
+ push(value: T): Promise<void>;
8
+ private pump;
9
+ }
@@ -0,0 +1,44 @@
1
+ /** Coalesces only queued values; the in-flight state is allowed to finish. */
2
+ export class LatestStateQueue {
3
+ constructor(transmit) {
4
+ this.transmit = transmit;
5
+ this.pending = null;
6
+ this.running = false;
7
+ }
8
+ push(value) {
9
+ return new Promise((resolve, reject) => {
10
+ if (this.pending) {
11
+ this.pending.value = value;
12
+ this.pending.waiters.push({ resolve, reject });
13
+ }
14
+ else {
15
+ this.pending = { value, waiters: [{ resolve, reject }] };
16
+ }
17
+ this.pump();
18
+ });
19
+ }
20
+ pump() {
21
+ if (this.running)
22
+ return;
23
+ this.running = true;
24
+ void (async () => {
25
+ while (this.pending) {
26
+ const current = this.pending;
27
+ this.pending = null;
28
+ try {
29
+ await this.transmit(current.value);
30
+ for (const waiter of current.waiters)
31
+ waiter.resolve();
32
+ }
33
+ catch (error) {
34
+ for (const waiter of current.waiters)
35
+ waiter.reject(error);
36
+ }
37
+ }
38
+ })().finally(() => {
39
+ this.running = false;
40
+ if (this.pending)
41
+ this.pump();
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,7 @@
1
+ import type { OpenRTCRoomHandle } from 'openrtc';
2
+ import type { NetcodeRuntime } from './types.js';
3
+ /**
4
+ * Adapts one OpenRTC 2.0 capability handle to netcode's transport-only runtime
5
+ * contract. It never creates a second room, user scope, or base space.
6
+ */
7
+ export declare function runtimeFromRoom(room: OpenRTCRoomHandle): NetcodeRuntime;
@@ -0,0 +1,88 @@
1
+ function normalized(value) {
2
+ return value.trim().toUpperCase();
3
+ }
4
+ function assertRoom(room, requested) {
5
+ if (normalized(room.id) !== normalized(requested)) {
6
+ throw new Error(`Activated OpenRTC room '${room.id}' cannot join '${requested}'.`);
7
+ }
8
+ }
9
+ function peerMember(peer) {
10
+ const peerId = String(peer.nodeId ?? peer.id ?? peer.deviceId ?? '');
11
+ return {
12
+ nodeId: peerId,
13
+ userId: typeof peer.userId === 'string' ? peer.userId : undefined,
14
+ ticket: typeof peer.ticket === 'string' ? peer.ticket : undefined,
15
+ joinedAt: typeof peer.connectedAt === 'number' ? peer.connectedAt : Date.now(),
16
+ lastSeenAt: Date.now(),
17
+ };
18
+ }
19
+ /**
20
+ * Adapts one OpenRTC 2.0 capability handle to netcode's transport-only runtime
21
+ * contract. It never creates a second room, user scope, or base space.
22
+ */
23
+ export function runtimeFromRoom(room) {
24
+ const connections = () => room.diagnostics.connections();
25
+ return {
26
+ managedConnectionLifecycle: true,
27
+ channels: room.channels,
28
+ initialize: async () => undefined,
29
+ start: async () => undefined,
30
+ stop: async () => undefined,
31
+ getNodeId: async () => {
32
+ const status = await room.diagnostics.status();
33
+ const nodeId = typeof status.localNodeId === 'string' ? status.localNodeId.trim() : '';
34
+ if (!nodeId)
35
+ throw new Error('The activated OpenRTC room has no local peer identity yet.');
36
+ return nodeId;
37
+ },
38
+ createRoom: async (roomId = room.id) => {
39
+ assertRoom(room, roomId);
40
+ return normalized(room.id);
41
+ },
42
+ joinRoom: async (roomId) => {
43
+ assertRoom(room, roomId);
44
+ return connections();
45
+ },
46
+ leaveRoom: async (roomId) => {
47
+ assertRoom(room, roomId);
48
+ await room.leave();
49
+ },
50
+ watchRoom: (roomId, callback) => {
51
+ assertRoom(room, roomId);
52
+ return room.peers.watch((peers) => callback(peers.map((peer) => peerMember(peer))));
53
+ },
54
+ getRoomMembers: async (roomId) => {
55
+ assertRoom(room, roomId);
56
+ return room.peers.listConnected()
57
+ .map((peer) => peerMember(peer));
58
+ },
59
+ onConnection: (callback) => {
60
+ const seen = new Set();
61
+ const publish = (connection) => {
62
+ const id = String(connection.id ?? connection.remoteNodeId ?? '');
63
+ if (!id || seen.has(id))
64
+ return;
65
+ seen.add(id);
66
+ callback(connection);
67
+ };
68
+ connections().forEach(publish);
69
+ return room.diagnostics.onConnection((connection) => {
70
+ publish(connection);
71
+ });
72
+ },
73
+ getConnections: connections,
74
+ connectByTicket: ({ ticket, timeoutMs }) => room.peers.connect({ ticket, timeoutMs }),
75
+ // The room capability already authorized the peer route. A protocol
76
+ // channel is not another admission avenue and must not replace that
77
+ // lifecycle scope with the channel identifier (which would trigger a
78
+ // second scoped dial on every send while the new scope is absent).
79
+ connectScopedChannel: (options) => room.channels.connectScoped({
80
+ ...options,
81
+ scope: `v2:room:${room.id}`,
82
+ existingRouteOnly: true,
83
+ }),
84
+ onIncomingChannelStream: (channelId, callback) => room.channels.onIncomingChannel(channelId, callback),
85
+ getApplicationReadyConnections: () => connections().filter((connection) => typeof connection.isReadyForApplicationPayload !== 'function'
86
+ || connection.isReadyForApplicationPayload()),
87
+ };
88
+ }
package/dist/types.d.ts CHANGED
@@ -1,26 +1,41 @@
1
- import type { OpenRTC } from 'openrtc';
2
- import type { RuntimeApplicationPayloadReadinessOptions as OpenRtcApplicationPayloadReadinessOptions, RuntimeClient } from 'openrtc/runtime';
1
+ import type { RuntimeApplicationPayloadReadinessOptions as OpenRtcApplicationPayloadReadinessOptions, RuntimeIncomingStream, RuntimeScopedChannelOptions, RuntimeScopedLogicalChannel } from 'openrtc/runtime';
2
+ import type { OpenRTCRoomHandle } from 'openrtc';
3
3
  import type { MetadataBody, NetcodeEnvelope, ObjectRemoveBody, ObjectSnapshotBody, ObjectUpsertBody, StatePatchBody, StateSnapshotBody, UserMessageBody, VoiceSignalBody } from './protocol.js';
4
- type OpenrtcClientOptions = Parameters<typeof OpenRTC>[0];
5
- export type NetcodeRuntime = RuntimeClient;
4
+ export interface NetcodeRuntime {
5
+ /**
6
+ * The activated capability owns discovery and physical peer lifecycle.
7
+ * Protocol layers must observe its connections instead of issuing a
8
+ * second ticket dial for the same avenue.
9
+ */
10
+ managedConnectionLifecycle?: boolean;
11
+ initialize?(): Promise<void> | void;
12
+ start?(): Promise<void> | void;
13
+ stop?(): Promise<void> | void;
14
+ getNodeId(): Promise<string>;
15
+ createRoom(roomId?: string): Promise<string>;
16
+ joinRoom(roomId: string, options?: {
17
+ bootstrapPeers?: boolean;
18
+ }): Promise<RuntimeConnectionLike[]>;
19
+ leaveRoom(roomId: string): Promise<void>;
20
+ watchRoom(roomId: string, callback: (members: RuntimeMemberLike[]) => void): () => void;
21
+ getRoomMembers(roomId: string): Promise<RuntimeMemberLike[]>;
22
+ onConnection(callback: (connection: RuntimeConnectionLike) => void): () => void;
23
+ getConnections(): RuntimeConnectionLike[];
24
+ connectByTicket(target: {
25
+ ticket: string;
26
+ timeoutMs?: number;
27
+ }): Promise<RuntimeConnectionLike>;
28
+ connectScopedChannel(options: RuntimeScopedChannelOptions): Promise<RuntimeScopedLogicalChannel>;
29
+ onIncomingChannelStream(channelId: string, callback: (stream: RuntimeIncomingStream) => boolean | void): () => void;
30
+ getApplicationReadyConnections(options?: RuntimeApplicationPayloadReadinessOptions): RuntimeConnectionLike[];
31
+ channels?: OpenRTCRoomHandle['channels'];
32
+ }
6
33
  export type NetcodeReliability = 'reliable';
7
34
  export interface NetcodeOptions {
8
35
  runtime?: NetcodeRuntime;
9
- apiKey?: OpenrtcClientOptions['apiKey'];
10
- projectId?: OpenrtcClientOptions['projectId'];
11
- authMode?: OpenrtcClientOptions['authMode'];
12
- discoveryMode?: OpenrtcClientOptions['discoveryMode'];
13
- allowAnonymousHostedDefaults?: OpenrtcClientOptions['allowAnonymousHostedDefaults'];
14
- space?: OpenrtcClientOptions['space'];
15
- spaceKey?: OpenrtcClientOptions['spaceKey'];
16
- spaceTokenProvider?: NonNullable<OpenrtcClientOptions>['spaceTokenProvider'];
17
- storagePrefix?: OpenrtcClientOptions['storagePrefix'];
18
- nodeIdPersistence?: OpenrtcClientOptions['nodeIdPersistence'];
19
- transports?: OpenrtcClientOptions['transports'];
20
- transportPriority?: OpenrtcClientOptions['transportPriority'];
36
+ /** Preferred 2.0 path: one already-activated ephemeral match room. */
37
+ room?: OpenRTCRoomHandle;
21
38
  preferredPayloadTransports?: RuntimeApplicationPayloadReadinessOptions['preferredTransports'];
22
- strictMode?: OpenrtcClientOptions['strictMode'];
23
- turnCredentialsProvider?: NonNullable<OpenrtcClientOptions>['turnCredentialsProvider'];
24
39
  displayName?: string;
25
40
  maxPeers?: number;
26
41
  localFallback?: boolean;
@@ -235,6 +250,7 @@ export type RuntimeConnectionLike = {
235
250
  parallelTransport?: string | null;
236
251
  };
237
252
  getAvailableTransports?(): string[];
253
+ isReadyForApplicationPayload?(options?: RuntimeApplicationPayloadReadinessOptions): boolean;
238
254
  onUpgradeStateChange?(callback: (state: 'none' | 'upgrading' | 'upgraded' | 'failed') => void): void;
239
255
  requestWebRTCUpgrade?(reason?: string): void;
240
256
  send(message: unknown): Promise<void> | void;
@@ -253,4 +269,3 @@ export type RuntimeMemberLike = {
253
269
  metadata?: string | Record<string, unknown> | null;
254
270
  };
255
271
  export type RuntimeEnvelopeBody = UserMessageBody | StateSnapshotBody | StatePatchBody | ObjectSnapshotBody | ObjectUpsertBody | ObjectRemoveBody | MetadataBody | VoiceSignalBody | Record<string, unknown>;
256
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openrtc-netcode",
3
- "version": "1.0.0",
3
+ "version": "2.0.0-rc.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -42,7 +42,7 @@
42
42
  "test:watch": "vitest"
43
43
  },
44
44
  "dependencies": {
45
- "openrtc": "^1.0.0"
45
+ "openrtc": "2.0.0-rc.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "^24.10.1",