openrtc 1.0.27 → 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.
Files changed (67) hide show
  1. package/README.md +143 -205
  2. package/dist/DelegatingRuntimeAdapter-DqfHkjLy.d.ts +373 -0
  3. package/dist/ITransport-BsPcaov7.d.ts +16 -0
  4. package/dist/OpenRTCShared-TKAQLONA.js +1 -0
  5. package/dist/{assembly-CscFVHYK.d.ts → OpenRTCShared-ZQPu5LqL.d.ts} +255 -28
  6. package/dist/WasmBridge-2A22U7RU.js +1 -0
  7. package/dist/auth/index.js +1 -1
  8. package/dist/auth/internal.js +1 -1
  9. package/dist/{capabilities-CaqXOIUU.d.ts → capabilities-YSskrE8H.d.ts} +1 -1
  10. package/dist/chunk-2QHDEGVX.js +1 -0
  11. package/dist/chunk-3USHQ7QW.js +3 -0
  12. package/dist/chunk-5LRLWIT5.js +1 -0
  13. package/dist/chunk-6TAVJ46R.js +1 -0
  14. package/dist/chunk-7Z6N46RB.js +2 -0
  15. package/dist/chunk-A3IAG6EL.js +1 -0
  16. package/dist/chunk-BXFXPIXO.js +1 -0
  17. package/dist/chunk-F2XGNLXL.js +2 -0
  18. package/dist/chunk-GW7P3D54.js +1 -0
  19. package/dist/chunk-IEQTFQ3Q.js +1 -0
  20. package/dist/chunk-K37WVIZL.js +1 -0
  21. package/dist/chunk-N26S7V4N.js +1 -0
  22. package/dist/chunk-N4SX7C3W.js +2 -0
  23. package/dist/chunk-NB4H5TP3.js +1 -0
  24. package/dist/chunk-NT5YHZQH.js +1 -0
  25. package/dist/chunk-PODAMIL6.js +2 -0
  26. package/dist/chunk-RD3JEGGF.js +2 -0
  27. package/dist/chunk-UEYM6WTT.js +2 -0
  28. package/dist/chunk-VK6KX433.js +1 -0
  29. package/dist/chunk-YBXGNKM7.js +2 -0
  30. package/dist/chunk-YQWQDTQ3.js +2 -0
  31. package/dist/factories-SIVMTIHJ.js +1 -0
  32. package/dist/index.d.ts +12 -65
  33. package/dist/index.js +1 -1
  34. package/dist/ipcFactory-QY44OIKA.js +1 -0
  35. package/dist/native.d.ts +10 -15
  36. package/dist/native.js +1 -1
  37. package/dist/openrtc_bg.wasm +0 -0
  38. package/dist/runtime/WasmRuntimeAdapter.d.ts +3 -3
  39. package/dist/runtime/WasmRuntimeAdapter.js +1 -1
  40. package/dist/runtime/device-status.d.ts +3 -2
  41. package/dist/runtime/index.d.ts +100 -15
  42. package/dist/runtime/index.js +2 -1
  43. package/dist/runtime/legacy.d.ts +18 -0
  44. package/dist/runtime/legacy.js +1 -0
  45. package/dist/runtime/tauri.d.ts +4 -4
  46. package/dist/runtime/tauri.js +1 -1
  47. package/dist/{tauri-BpsecNrp.d.ts → tauri-Cz9n17g8.d.ts} +2 -2
  48. package/dist/testing.d.ts +30 -0
  49. package/dist/testing.js +1 -0
  50. package/dist/transport/index.d.ts +47 -7
  51. package/dist/transport/index.js +1 -1
  52. package/dist/{types-zT2QwuCv.d.ts → types-BVJr065k.d.ts} +43 -3
  53. package/dist/types-DNl4KHHY.d.ts +195 -0
  54. package/dist/{types-BJU2GoVb.d.ts → types-DkgaCyqS.d.ts} +11 -17
  55. package/package.json +19 -4
  56. package/dist/DelegatingRuntimeAdapter-Cg3jFk1b.d.ts +0 -133
  57. package/dist/chunk-4IK5EKHY.js +0 -2
  58. package/dist/chunk-BW6OKBHV.js +0 -2
  59. package/dist/chunk-EVJYUIBK.js +0 -1
  60. package/dist/chunk-H5VWKP4Q.js +0 -2
  61. package/dist/chunk-HYHVKPQN.js +0 -3
  62. package/dist/chunk-LAUABWCB.js +0 -2
  63. package/dist/chunk-OCSZA6PK.js +0 -2
  64. package/dist/chunk-OMDHDMDJ.js +0 -1
  65. package/dist/chunk-QT2ASNI3.js +0 -1
  66. package/dist/framing-zRvEKOld.d.ts +0 -29
  67. package/dist/spaceTokens-CiwcKKr2.d.ts +0 -297
package/README.md CHANGED
@@ -1,228 +1,166 @@
1
- # OpenRTC TypeScript Package
1
+ # OpenRTC
2
2
 
3
- The TypeScript package is the host-facing layer for `openrtc`.
3
+ OpenRTC is a provider-neutral peer coordination and transport SDK for browsers,
4
+ desktop applications, and mobile applications. The 2.0 API is capability based:
5
+ constructing a client is local and side-effect free, and network work starts only
6
+ when the application activates a device, space, room, or ticket handle.
4
7
 
5
- It does not implement a second realtime engine. It exposes the Rust runtime to:
6
- - browser apps through WASM plus the scoped browser Firebase signaling layer
7
- - native apps through a generic IPC contract, with first-party Tauri wiring in `openrtc-tauri`
8
+ The core is message-agnostic. Named channels are the application protocol
9
+ extension boundary; they do not replace the incoming router or authorize a
10
+ parallel lifecycle owner.
8
11
 
9
- ## Recommended Usage
12
+ ## Install
10
13
 
11
- Use the OpenRTC client entry points for new integrations, and choose the
12
- avenue that matches your product:
14
+ ```bash
15
+ pnpm add openrtc
16
+ ```
17
+
18
+ ## Fast prototype
13
19
 
14
- - `user-scoped` for a signed-in user's durable device mesh
15
- - `space` for a small live shared namespace
16
- - rooms for intentional group membership
17
- - tickets/share grants for explicit one-off pairing without a roster
20
+ Only a public API key is required for a bounded ephemeral space:
18
21
 
19
22
  ```ts
20
23
  import { OpenRTC } from 'openrtc';
21
24
 
22
- const client = OpenRTC({
23
- apiKey: 'pk_live_...',
24
- discoveryMode: 'user-scoped',
25
- authMode: 'external',
25
+ const rtc = OpenRTC({ apiKey: import.meta.env.VITE_OPENRTC_API_KEY });
26
+ const cursors = await rtc.spaces.join('portfolio-cursors', {
27
+ access: 'capability',
28
+ identity: 'ephemeral',
29
+ payload: 'latest-state',
30
+ });
31
+
32
+ const stop = cursors.peers.watch((peers) => console.log(peers));
33
+
34
+ // Later
35
+ stop();
36
+ await cursors.leave();
37
+ await rtc.close();
38
+ ```
39
+
40
+ The constructor performs no network request, storage access, authentication,
41
+ attestation, timer creation, WASM load, or transport startup.
42
+
43
+ ## Authenticated devices
44
+
45
+ Your application owns login and supplies a short-lived assertion from its
46
+ registered OIDC/JWKS provider. OpenRTC validates it, binds the installation's
47
+ device key, and issues scoped gateway grants.
48
+
49
+ ```ts
50
+ const auth = {
51
+ getAssertion: ({ forceRefresh }: { forceRefresh: boolean }) =>
52
+ fetch('/api/openrtc/assertion', {
53
+ method: 'POST',
54
+ headers: { 'X-Force-Refresh': String(forceRefresh) },
55
+ }).then((response) => response.text()),
56
+ };
57
+
58
+ const rtc = OpenRTC({
59
+ apiKey: import.meta.env.VITE_OPENRTC_API_KEY,
60
+ auth,
61
+ });
62
+
63
+ const devices = await rtc.devices.start({
64
+ auth,
65
+ autoConnect: 'online',
66
+ });
67
+ ```
68
+
69
+ Consumer apps own login UX, product authorization, IdP registration, and
70
+ platform-attestation setup. OpenRTC owns assertion validation, device binding,
71
+ grant issuance and refresh, revocation, budgets, metering, and abuse controls.
72
+
73
+ ## Rooms
74
+
75
+ Rooms default to ephemeral membership:
76
+
77
+ ```ts
78
+ const room = await rtc.rooms.join('match-123', {
79
+ access: 'capability',
80
+ membership: 'ephemeral',
81
+ maxPeers: 8,
26
82
  });
83
+ ```
84
+
85
+ Durable membership is an advanced capability and must be enabled in the
86
+ developer portal and requested by the application:
27
87
 
28
- await client.connect();
29
- await client.devices.startSession({
30
- deviceName: 'Work Laptop',
88
+ ```ts
89
+ const team = await rtc.rooms.join('team', {
90
+ access: 'authenticated',
91
+ membership: 'durable',
92
+ auth,
31
93
  });
32
94
  ```
33
95
 
34
- For normal app code, the default flow is:
96
+ Every long-lived capability has `close()`; spaces and rooms also have
97
+ `leave()`. One handle activates exactly one avenue.
98
+
99
+ ## Optional trust adapters
35
100
 
36
- 1. discover or select a device
37
- 2. open a named logical app channel with `client.channels.connect({ device, channelId })`
38
- 3. send and receive app payloads on that channel
101
+ Attestation is evaluated at device enrollment, key rotation, recovery, or risk
102
+ escalation—not as a connection heartbeat.
39
103
 
40
- `channels.connect(...)` owns the peer dial, readiness wait, channel selection,
41
- roster-ticket reuse, and default `session` lifecycle scope. Use `client.peers.connect(...)`,
42
- `client.channels.openBi(...)`, `connectScoped(...)`, `openPeerBi(...)`, or
43
- `openPeerUni(...)` only when you need explicit lifecycle, stream, or transport
44
- control.
104
+ ```ts
105
+ import { FirebaseAppCheckAttestationProvider } from '@openrtc/trust-firebase-app-check';
106
+
107
+ const rtc = OpenRTC({
108
+ apiKey,
109
+ auth,
110
+ trust: {
111
+ attestation: new FirebaseAppCheckAttestationProvider({ appCheck }),
112
+ },
113
+ });
114
+ ```
45
115
 
46
- ## Naming Guide
116
+ Managed Firebase App Check, Apple App Attest, and Play Integrity are optional
117
+ packages. A consumer backend may instead validate platform evidence and issue
118
+ the registered OIDC assertion; that is the canonical production integration.
47
119
 
48
- Prefer the short app-facing names in new code:
120
+ ## Usage controls
49
121
 
50
122
  ```ts
51
- import { OpenRTC, spaceToken } from 'openrtc';
52
-
53
- const client = OpenRTC({
54
- apiKey: 'pk_live_...',
55
- discoveryMode: 'space',
56
- authMode: 'anonymous',
57
- space: 'team-canvas',
58
- spaceTokenProvider: spaceToken({
59
- apiKey: 'pk_live_...',
60
- space: 'team-canvas',
61
- }),
123
+ const rtc = OpenRTC({
124
+ apiKey,
125
+ usage: {
126
+ warnAtSessionCreditsUsd: 0.25,
127
+ maxSessionCreditsUsd: 0.50,
128
+ onUsage: console.log,
129
+ onWarning: console.warn,
130
+ },
62
131
  });
132
+
133
+ rtc.usage.estimate({ operation: 'coordination.connection.open', units: 3 });
63
134
  ```
64
135
 
65
- - Use `space` instead of `spaceKey` in app code.
66
- - Use `spaceTokenProvider` and `spaceToken(...)` for scoped shared-space auth.
67
- - Use `client.devices.*`, `client.rooms.*`, `client.tickets.*`,
68
- `client.channels.*`, and `client.peers.*` before reaching for lower-level
69
- runtime names.
70
-
71
- ## Discovery Avenues
72
-
73
- OpenRTC discovery is not one generic live device list:
74
-
75
- - User-scope/user-device is the persistent owned-device avenue. Devices remain
76
- visible while `presenceStatus` degrades `online` -> `idle` -> `offline`, and
77
- are removed only by explicit deletion or offline retention expiry.
78
- - Spaces and rooms are ephemeral collaboration avenues. Active rosters may
79
- filter or clean up stale entries.
80
- - Ticket-only/share flows do not use a hosted discovery roster; the ticket or
81
- grant is the bootstrap avenue.
82
-
83
- Status-aware device APIs should preserve presence-only changes and merge
84
- authoritative roster refreshes with live watch state so no avenue-specific
85
- device disappears just because one read model missed it.
86
-
87
- ## What This Package Owns
88
- - runtime factories and adapters
89
- - auth context injection
90
- - Pluto hosted auth helpers
91
- - browser Firebase signaling/rooms wiring
92
- - host wiring for WASM and generic IPC
93
-
94
- ## What This Package Does Not Own
95
- - native Tauri API bindings
96
- - peer discovery or lifecycle policy beyond the browser Firebase host layer
97
- - iroh connection lifecycle
98
-
99
- Those responsibilities belong to the Rust runtime and the host platform adapter.
100
-
101
- ## Message Model
102
- - `openrtc` is message-agnostic above the runtime layer.
103
- - The runtime only defines internal control messages such as handshake and heartbeat.
104
- - Application payload protocols, including file transfer, should be implemented on top of generic runtime connections and streams.
105
- - If an app needs richer payload ergonomics, add generic stream/connection primitives to the runtime instead of adding app-specific message types to `pluto-rtc`.
106
-
107
- ## Protocol Extension Model
108
-
109
- The recommended TypeScript extension path is:
110
-
111
- 1. choose the public avenue (`user-scoped`, `space`, room, or ticket/share)
112
- 2. open a named logical channel with `client.channels.connect(...)`
113
- 3. implement your own framing and message semantics in app code
114
-
115
- This keeps the runtime responsible for peer/session establishment while leaving
116
- full control of channel/message specifics to the developer.
117
-
118
- Register a `RuntimeChannelDescriptor` with `client.channels.register(...)` and
119
- install one process-level `client.channels.onIncomingChannel(...)` handler when
120
- the protocol needs explicit readiness, routing, or framing metadata. This is an
121
- application protocol extension. It does not replace the incoming router or
122
- grant authority over admission, peer scopes, dialing, retry, transport
123
- promotion, recovery, or settlement.
124
-
125
- `OpenRTCClient` still inherits `RuntimeClient` compatibility methods, and
126
- `openrtc/runtime`, `client.peers.addScope()` / `releaseScope()`, and
127
- `client.advanced` expose authority-capable manual surfaces. They are not the
128
- recommended extension model and must not be used to build a parallel lifecycle.
129
- Their narrowing is future-version work.
130
-
131
- Advanced custom ALPN protocol plugins are a Rust-first/native-first feature.
132
- Browser parity is guaranteed at the connected-peer stream layer, not at the
133
- full ALPN plugin layer.
134
-
135
- For applications that want a reusable file protocol without making it part of
136
- the core runtime, install `openrtc-file-transfer`. It implements versioned,
137
- bounded file framing, acknowledgement, progress, cancellation, optional
138
- integrity verification, and streaming receive sinks. Modern clients send
139
- receiver-acknowledged segments through OpenRTC's current application route;
140
- the named-channel stream carrier remains compatibility fallback.
141
- Filesystem destinations, persistent queues, history, acceptance prompts, and
142
- product policy remain consumer-owned.
143
-
144
- ## Main Surfaces
145
-
146
- ### Root Package
147
- - `OpenRTC()`
148
- - `OpenRTC.native()`
149
-
150
- ### Native-only Entrypoint
151
- - `openrtc/native`
152
- - `createNativeOpenRTC(options, bridge)`
153
- - excludes the browser WASM adapter and binary from Tauri webview bundles
154
-
155
- ### Runtime Secondary Entrypoint
156
- - `openrtc/runtime`
157
- - `RuntimeClient`
158
- - `createWasmClient()` and `createIpcClient(..., bridge)` (legacy compatibility)
159
- - `IpcRuntimeAdapter`
160
- - `WasmRuntimeAdapter`
161
- - `PlutoIpcBridge` types for advanced host integrations
162
-
163
- ### Tauri Package
164
- - `openrtc-tauri`
165
- - `createTauriIpcBridge()`
166
- - `TauriRuntimeAdapter`
167
- - Rust plugin crate: `openrtc-tauri-plugin`
168
- - `openrtc/runtime/tauri` remains as a deprecated compatibility shim for one release cycle
169
-
170
- For Tauri desktop/mobile apps, use `createNativeOpenRTC(options, bridge)` from
171
- `openrtc/native` with the `openrtc-tauri` bridge and register
172
- `openrtc-tauri-plugin` in the Rust Tauri
173
- builder. Do not copy product-owned RTC command files into new apps. The plugin
174
- owns the native IPC command set and delegates lifecycle, discovery, presence,
175
- auto-connect, and connection state to one `openrtc::client::Client`. Do not use
176
- `OpenRTC(options)` or the compatibility `OpenRTC.native(options)` entry inside a
177
- Tauri shell unless you intentionally want the
178
- browser/WASM runtime for a prototype; that path bypasses the native Rust runtime
179
- or retains browser-runtime bundle reachability and can hide native
180
- lifecycle/presence issues from tests.
181
-
182
- Mobile hosts should forward connectivity-restored callbacks through
183
- `client.advanced.notifyNetworkChange(reason)`. The Tauri plugin passes this hint
184
- to the existing Iroh endpoint so it can reconsider relay and direct paths; it
185
- does not create a second OpenRTC dial or retry loop.
186
-
187
- ## Auth Model
188
- - `anonymous`: no Pluto auth required
189
- - `required`: Pluto auth required; the SDK may initiate Pluto SSO
190
- - `external`: Pluto auth still required, but the host app acquires it and injects it into the runtime
191
-
192
- ## Security Boundary
193
-
194
- Iroh authenticates endpoint keys and encrypts transport traffic. OpenRTC's
195
- managed avenues add scoped session-token admission and application payload
196
- encryption. These protections are cumulative: transport connectivity alone is
197
- not permission to invoke a product action.
198
-
199
- - Prefer `client.devices`, `client.rooms`, `client.tickets`, and
200
- `client.channels` managed flows; they retain admission and protected-route
201
- checks across transport replacement.
202
- - Treat raw endpoint tickets and low-level manual peer APIs as transport
203
- primitives. A consumer using them must define its own authorization boundary.
204
- - Authorize every privileged message against the accepted OpenRTC scope and the
205
- consumer application's current ACL. Never trust a payload's self-declared
206
- sender, role, or scope.
207
- - Keep compound tickets and session tokens out of logs, telemetry, query
208
- strings, crash reports, and UI diagnostics. Use URL fragments for intentional
209
- browser handoff and scrub them immediately after capture.
210
- - Revocation must invalidate the matching scope and product ACL; reconnecting a
211
- transport must not restore revoked access.
212
-
213
- The full owner and release contract is in
214
- [`docs/architecture/application-security-and-delivery-contract.md`](../../docs/architecture/application-security-and-delivery-contract.md).
215
-
216
- ## Design Rule
217
- If a feature requires discovery, signaling, presence, or lifecycle state, the TypeScript package should delegate to Rust rather than reimplement it locally, except for the scoped browser Firebase host layer where the official browser SDK is the source of truth. In both cases, keep the avenue semantics intact: persistent user-device rosters are not space/room live rosters.
218
-
219
- ## Allowed vs. Not Allowed
220
-
221
- - Allowed:
222
- - host/runtime adapter selection
223
- - auth injection and hosted Pluto auth helpers
224
- - thin, typed wrappers over Rust-owned state
225
- - Not allowed:
226
- - TypeScript-owned discovery or lifecycle engines
227
- - TypeScript-owned peer identity policy
228
- - app-specific protocol messages embedded into the runtime
136
+ The client ceiling is an additional local guard. Server budgets and developer
137
+ manifest limits remain authoritative.
138
+
139
+ ## Native and WASM
140
+
141
+ ```ts
142
+ import { createNativeOpenRTC } from 'openrtc/native';
143
+ import { createTauriIpcBridge } from 'openrtc-tauri/ipc';
144
+
145
+ const rtc = createNativeOpenRTC({ apiKey, auth }, createTauriIpcBridge());
146
+ ```
147
+
148
+ Native hosts keep one Ed25519 installation key in host secure storage. Browsers
149
+ use a non-extractable WebCrypto key in IndexedDB when supported. The Rust and
150
+ WASM clients use the same provider-neutral avenue-grant contract as TypeScript.
151
+
152
+ Low-level runtime access is intentionally isolated in `openrtc/runtime` for
153
+ transport authors, migration harnesses, and diagnostics. Test endpoint
154
+ overrides live only in `openrtc/testing`.
155
+
156
+ ## Extensions
157
+
158
+ - `y-openrtc` adapts one activated room to Yjs.
159
+ - `openrtc-netcode` owns matches, replicated state, latest-state transforms,
160
+ chat/control, and optional voice helpers.
161
+ - `openrtc-file-transfer` owns bounded, acknowledged, resumable file transfer.
162
+
163
+ Relay, durable membership, managed attestation, MoQ, and BLE require both
164
+ portal enablement and explicit runtime opt-in. During the public RC, avenues
165
+ default to 8 peers; 9-12 peers additionally require runtime `advancedFanout`
166
+ and an operator-reviewed app allowlist.