@urun-sh/core 0.3.3 → 0.3.5
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/CHANGELOG.md +48 -0
- package/dist/index.browser.d.mts +8 -2
- package/dist/index.browser.d.ts +8 -2
- package/dist/index.browser.js +2 -2
- package/dist/index.browser.mjs +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -4
- package/dist/index.mjs +1 -1
- package/dist/internal.browser.d.mts +1 -1
- package/dist/internal.browser.d.ts +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{stream-data-Bl4UHVAa.d.mts → stream-data-iemsO_1p.d.mts} +8 -0
- package/dist/{stream-data-Bl4UHVAa.d.ts → stream-data-iemsO_1p.d.ts} +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- **WT uplink lanes now share ONE datagram writer (`getWriter` lock).**
|
|
6
|
+
`WritableStream.getWriter()` LOCKS the stream — the WHATWG contract is one
|
|
7
|
+
writer at a time. `WebTransportSession.start()` built its uplink sink by
|
|
8
|
+
calling `datagrams.writable.getWriter()` once PER LANE, so on a leg granted
|
|
9
|
+
more than one uplink the SECOND lane threw
|
|
10
|
+
`Cannot create writer when WritableStream is locked` and reverted to a WebRTC
|
|
11
|
+
produce path that a fully-granted WT-only leg does not have (qwen-avatar
|
|
12
|
+
2026-09-01, iPhone Safari AND desktop Chrome: `WT video uplink failed to
|
|
13
|
+
engage (...)` on every session; the camera lane was dead from bring-up).
|
|
14
|
+
Audio-only legs (qwen-voice) never hit it — exactly one lane, one acquire.
|
|
15
|
+
The writer is now acquired lazily ONCE per session, shared by every lane, and
|
|
16
|
+
`releaseLock()`-ed on stop/death. The pre-existing fakes handed back a fresh
|
|
17
|
+
writer on every call, hiding the double-acquire; the new
|
|
18
|
+
`wt-uplink-writer-lock.test.ts` fake implements the real lock contract.
|
|
19
|
+
- **A dead WT-only leg now LOUD-FAILS instead of silently "failing over" to a
|
|
20
|
+
transport that was never dialled.** On a fully-granted leg the negotiator
|
|
21
|
+
calls `webRtcDial.skip()` — no `RTCPeerConnection`, no mediasoup Device, no
|
|
22
|
+
server media transports. When QUIC then died mid-session, `armFailover`
|
|
23
|
+
re-drove the deferred dial fire-and-forget and immediately awaited
|
|
24
|
+
`startWebRtc()`, whose `WebRtcSession.start()` awaits a `track` event that a
|
|
25
|
+
never-dialled leg may never receive. The await never settled: `session` was
|
|
26
|
+
never reassigned (`activeTransport` kept reporting the DEAD `'webtransport'`),
|
|
27
|
+
`transport.established` was never notified, `onTransportChange` never fired,
|
|
28
|
+
and NOTHING reached the app — a black pane behind a misleading
|
|
29
|
+
`quic died mid-session, failing over to webrtc` line (qwen-avatar
|
|
30
|
+
2026-09-01). The failover is now bounded by `webRtcFailoverDeadlineMs`
|
|
31
|
+
(default 10s); on expiry the negotiator drops the stale session
|
|
32
|
+
(`activeTransport === null`), skips the false `transport.established(webrtc)`
|
|
33
|
+
notify, logs a specific `media transport lost — …` error naming the WT-only /
|
|
34
|
+
no-RTCPeerConnection condition, and surfaces it through the new
|
|
35
|
+
`onMediaTransportLost` seam (plumbed through `negotiateDialTransport`, which
|
|
36
|
+
also clears the stale track overrides and arms the WT retries). The warn line
|
|
37
|
+
itself no longer claims a WebRTC leg exists on a WT-only leg. The abandoned
|
|
38
|
+
WebRTC session is retained synchronously and stopped DIRECTLY on expiry (a
|
|
39
|
+
cleanup chained off the abandoned `start()` promise never runs in exactly the
|
|
40
|
+
never-settles case the deadline exists for, leaking the peer connection for
|
|
41
|
+
the life of the page), and both the adopt and the give-up paths are guarded
|
|
42
|
+
against a `disconnect()` — or a background WT re-upgrade — that landed while
|
|
43
|
+
`start()` was in flight.
|
|
44
|
+
- **A mid-session WT death no longer masquerades as a failed negotiation.**
|
|
45
|
+
`engage()`'s `await media.firstMedia` rejection escaped to the connect-path
|
|
46
|
+
catch, so a death minutes after a SUCCESSFUL dial wore the
|
|
47
|
+
`transport negotiation unavailable, staying on webrtc` line and re-drove the
|
|
48
|
+
deferred WebRTC dial a second time. It is now caught where it belongs; the
|
|
49
|
+
negotiator's failover path owns the death.
|
|
50
|
+
|
|
3
51
|
## 0.3.0
|
|
4
52
|
|
|
5
53
|
- **BREAKING (types): `SessionPhaseName` widens 9 → 11 members** — adds
|
package/dist/index.browser.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as AppOptions, f as App$1, ae as SessionPhase, ak as SessionStatus, ag as SessionPhaseName, A as AccessTokenOptions, $ as RuntimeArtifact, a0 as RuntimeArtifactDownload, T as Recording, aA as TransportState, a8 as Session$1, C as ChannelEndpoint, ax as TransportSession, h as AttachOptions, a9 as SessionDiagnostic, b as ActivationEvent, aj as SessionStatsSample, z as GenerationTick, X as RecordingsAccessor, a1 as RuntimeArtifactsAccessor, ac as SessionEndResult, al as SessionStream$1, as as StreamDataTransport, ab as SessionDocumentImpl, ar as StreamChunkOptions, m as ChunkReadable, P as Presence, v as DocConnector, x as DocTokenSupplier, w as DocServerUrlResolver, Z as RequestOptions, _ as RequestStreamOptions, aq as StoreOptions, ap as Store, k as ChannelMultiplexer, ad as SessionFailureKind, H as MediaSession, aw as TransportOfferResponse, aF as WtAudioLaneSeam, aG as WtAudioUplinkSeam, aN as WtVideoUplinkSeam, aM as WtDataUplinkSender, aK as WtDataLaneSink } from './stream-data-
|
|
2
|
-
export { c as ActivationState, i as AudioPlayoutOptions, D as DERIVED_LEG_SEP, n as DGRAM_HEADER_BYTES, r as DerivedLegRole, s as DgramHeader, u as DocConnectionState, G as GENERATION_TICK_EMIT_INTERVAL_MS, y as GENERATION_TICK_MAX_EXTRAPOLATION_MS, I as InboundStatsSample, M as MediaChunkBinding, B as MediaChunkSource, E as MediaChunkSourceFactory, F as MediaRecorderChunkSourceOptions, N as NegotiatorDataLaneSeam, J as NegotiatorOptions, K as PresenceState, O as PrewakeOptions, Q as PrewakeResult, R as PrewakeStatus, S as QuicStreamDataTransport, U as RecordingBucket, V as RecordingLifecycle, W as RecordingStatus, Y as ReleaseSessionBeaconOptions, a2 as RuntimeAvailability, a3 as RuntimeWakeDetail, a4 as RuntimeWakeGolden, a5 as RuntimeWakeReasonCode, a6 as SIGNALING_PROTOCOL_VERSION, a7 as STREAM_END, aa as SessionDocument, af as SessionPhaseError, ai as SessionStatsOptions, am as SessionText, an as SignalCarrier, ao as Signaling, at as TransportEstablishedNotify, au as TransportNegotiator, av as TransportOfferRequest, az as TransportSessionSignaling, aB as VideoPlayoutOptions, aC as WT_CONTROL_FRAME_MAX, aD as WT_DATA_STREAM_VERSION, aE as WatchGenerationTickOptions, aH as WtControlDecoder, aI as WtControlMessage, aJ as WtDataEnvelope, aL as WtDataStreamParser, aP as consumeWtDataStreams, aS as decodeStreamEnvelope, aU as derivedLegName, aV as derivedLegRole, aW as encodeStreamEnvelope, aX as encodeWtControlFrame, aY as isPendingRecording, aZ as mediaRecorderChunkSource, a_ as parseDgramHeader, a$ as prewake, b0 as releaseSessionBeacon, b3 as watchGenerationTick, b4 as writeDgramHeader } from './stream-data-
|
|
1
|
+
import { g as AppOptions, f as App$1, ae as SessionPhase, ak as SessionStatus, ag as SessionPhaseName, A as AccessTokenOptions, $ as RuntimeArtifact, a0 as RuntimeArtifactDownload, T as Recording, aA as TransportState, a8 as Session$1, C as ChannelEndpoint, ax as TransportSession, h as AttachOptions, a9 as SessionDiagnostic, b as ActivationEvent, aj as SessionStatsSample, z as GenerationTick, X as RecordingsAccessor, a1 as RuntimeArtifactsAccessor, ac as SessionEndResult, al as SessionStream$1, as as StreamDataTransport, ab as SessionDocumentImpl, ar as StreamChunkOptions, m as ChunkReadable, P as Presence, v as DocConnector, x as DocTokenSupplier, w as DocServerUrlResolver, Z as RequestOptions, _ as RequestStreamOptions, aq as StoreOptions, ap as Store, k as ChannelMultiplexer, ad as SessionFailureKind, H as MediaSession, aw as TransportOfferResponse, aF as WtAudioLaneSeam, aG as WtAudioUplinkSeam, aN as WtVideoUplinkSeam, aM as WtDataUplinkSender, aK as WtDataLaneSink } from './stream-data-iemsO_1p.mjs';
|
|
2
|
+
export { c as ActivationState, i as AudioPlayoutOptions, D as DERIVED_LEG_SEP, n as DGRAM_HEADER_BYTES, r as DerivedLegRole, s as DgramHeader, u as DocConnectionState, G as GENERATION_TICK_EMIT_INTERVAL_MS, y as GENERATION_TICK_MAX_EXTRAPOLATION_MS, I as InboundStatsSample, M as MediaChunkBinding, B as MediaChunkSource, E as MediaChunkSourceFactory, F as MediaRecorderChunkSourceOptions, N as NegotiatorDataLaneSeam, J as NegotiatorOptions, K as PresenceState, O as PrewakeOptions, Q as PrewakeResult, R as PrewakeStatus, S as QuicStreamDataTransport, U as RecordingBucket, V as RecordingLifecycle, W as RecordingStatus, Y as ReleaseSessionBeaconOptions, a2 as RuntimeAvailability, a3 as RuntimeWakeDetail, a4 as RuntimeWakeGolden, a5 as RuntimeWakeReasonCode, a6 as SIGNALING_PROTOCOL_VERSION, a7 as STREAM_END, aa as SessionDocument, af as SessionPhaseError, ai as SessionStatsOptions, am as SessionText, an as SignalCarrier, ao as Signaling, at as TransportEstablishedNotify, au as TransportNegotiator, av as TransportOfferRequest, az as TransportSessionSignaling, aB as VideoPlayoutOptions, aC as WT_CONTROL_FRAME_MAX, aD as WT_DATA_STREAM_VERSION, aE as WatchGenerationTickOptions, aH as WtControlDecoder, aI as WtControlMessage, aJ as WtDataEnvelope, aL as WtDataStreamParser, aP as consumeWtDataStreams, aS as decodeStreamEnvelope, aU as derivedLegName, aV as derivedLegRole, aW as encodeStreamEnvelope, aX as encodeWtControlFrame, aY as isPendingRecording, aZ as mediaRecorderChunkSource, a_ as parseDgramHeader, a$ as prewake, b0 as releaseSessionBeacon, b3 as watchGenerationTick, b4 as writeDgramHeader } from './stream-data-iemsO_1p.mjs';
|
|
3
3
|
import 'yjs';
|
|
4
4
|
import 'y-protocols/awareness';
|
|
5
5
|
|
|
@@ -1012,6 +1012,8 @@ declare class WebTransportSession implements MediaSession {
|
|
|
1012
1012
|
|
|
1013
1013
|
private decoderErrorsAt;
|
|
1014
1014
|
private writer;
|
|
1015
|
+
|
|
1016
|
+
private dgramWriter;
|
|
1015
1017
|
private deadCb;
|
|
1016
1018
|
private deadFired;
|
|
1017
1019
|
private stopped;
|
|
@@ -1055,6 +1057,10 @@ declare class WebTransportSession implements MediaSession {
|
|
|
1055
1057
|
start(): Promise<void>;
|
|
1056
1058
|
stop(): Promise<void>;
|
|
1057
1059
|
|
|
1060
|
+
private datagramWriter;
|
|
1061
|
+
|
|
1062
|
+
private releaseDatagramWriter;
|
|
1063
|
+
|
|
1058
1064
|
private dropUplinks;
|
|
1059
1065
|
onDead(cb: (reason: string) => void): void;
|
|
1060
1066
|
stats(): {
|
package/dist/index.browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as AppOptions, f as App$1, ae as SessionPhase, ak as SessionStatus, ag as SessionPhaseName, A as AccessTokenOptions, $ as RuntimeArtifact, a0 as RuntimeArtifactDownload, T as Recording, aA as TransportState, a8 as Session$1, C as ChannelEndpoint, ax as TransportSession, h as AttachOptions, a9 as SessionDiagnostic, b as ActivationEvent, aj as SessionStatsSample, z as GenerationTick, X as RecordingsAccessor, a1 as RuntimeArtifactsAccessor, ac as SessionEndResult, al as SessionStream$1, as as StreamDataTransport, ab as SessionDocumentImpl, ar as StreamChunkOptions, m as ChunkReadable, P as Presence, v as DocConnector, x as DocTokenSupplier, w as DocServerUrlResolver, Z as RequestOptions, _ as RequestStreamOptions, aq as StoreOptions, ap as Store, k as ChannelMultiplexer, ad as SessionFailureKind, H as MediaSession, aw as TransportOfferResponse, aF as WtAudioLaneSeam, aG as WtAudioUplinkSeam, aN as WtVideoUplinkSeam, aM as WtDataUplinkSender, aK as WtDataLaneSink } from './stream-data-
|
|
2
|
-
export { c as ActivationState, i as AudioPlayoutOptions, D as DERIVED_LEG_SEP, n as DGRAM_HEADER_BYTES, r as DerivedLegRole, s as DgramHeader, u as DocConnectionState, G as GENERATION_TICK_EMIT_INTERVAL_MS, y as GENERATION_TICK_MAX_EXTRAPOLATION_MS, I as InboundStatsSample, M as MediaChunkBinding, B as MediaChunkSource, E as MediaChunkSourceFactory, F as MediaRecorderChunkSourceOptions, N as NegotiatorDataLaneSeam, J as NegotiatorOptions, K as PresenceState, O as PrewakeOptions, Q as PrewakeResult, R as PrewakeStatus, S as QuicStreamDataTransport, U as RecordingBucket, V as RecordingLifecycle, W as RecordingStatus, Y as ReleaseSessionBeaconOptions, a2 as RuntimeAvailability, a3 as RuntimeWakeDetail, a4 as RuntimeWakeGolden, a5 as RuntimeWakeReasonCode, a6 as SIGNALING_PROTOCOL_VERSION, a7 as STREAM_END, aa as SessionDocument, af as SessionPhaseError, ai as SessionStatsOptions, am as SessionText, an as SignalCarrier, ao as Signaling, at as TransportEstablishedNotify, au as TransportNegotiator, av as TransportOfferRequest, az as TransportSessionSignaling, aB as VideoPlayoutOptions, aC as WT_CONTROL_FRAME_MAX, aD as WT_DATA_STREAM_VERSION, aE as WatchGenerationTickOptions, aH as WtControlDecoder, aI as WtControlMessage, aJ as WtDataEnvelope, aL as WtDataStreamParser, aP as consumeWtDataStreams, aS as decodeStreamEnvelope, aU as derivedLegName, aV as derivedLegRole, aW as encodeStreamEnvelope, aX as encodeWtControlFrame, aY as isPendingRecording, aZ as mediaRecorderChunkSource, a_ as parseDgramHeader, a$ as prewake, b0 as releaseSessionBeacon, b3 as watchGenerationTick, b4 as writeDgramHeader } from './stream-data-
|
|
1
|
+
import { g as AppOptions, f as App$1, ae as SessionPhase, ak as SessionStatus, ag as SessionPhaseName, A as AccessTokenOptions, $ as RuntimeArtifact, a0 as RuntimeArtifactDownload, T as Recording, aA as TransportState, a8 as Session$1, C as ChannelEndpoint, ax as TransportSession, h as AttachOptions, a9 as SessionDiagnostic, b as ActivationEvent, aj as SessionStatsSample, z as GenerationTick, X as RecordingsAccessor, a1 as RuntimeArtifactsAccessor, ac as SessionEndResult, al as SessionStream$1, as as StreamDataTransport, ab as SessionDocumentImpl, ar as StreamChunkOptions, m as ChunkReadable, P as Presence, v as DocConnector, x as DocTokenSupplier, w as DocServerUrlResolver, Z as RequestOptions, _ as RequestStreamOptions, aq as StoreOptions, ap as Store, k as ChannelMultiplexer, ad as SessionFailureKind, H as MediaSession, aw as TransportOfferResponse, aF as WtAudioLaneSeam, aG as WtAudioUplinkSeam, aN as WtVideoUplinkSeam, aM as WtDataUplinkSender, aK as WtDataLaneSink } from './stream-data-iemsO_1p.js';
|
|
2
|
+
export { c as ActivationState, i as AudioPlayoutOptions, D as DERIVED_LEG_SEP, n as DGRAM_HEADER_BYTES, r as DerivedLegRole, s as DgramHeader, u as DocConnectionState, G as GENERATION_TICK_EMIT_INTERVAL_MS, y as GENERATION_TICK_MAX_EXTRAPOLATION_MS, I as InboundStatsSample, M as MediaChunkBinding, B as MediaChunkSource, E as MediaChunkSourceFactory, F as MediaRecorderChunkSourceOptions, N as NegotiatorDataLaneSeam, J as NegotiatorOptions, K as PresenceState, O as PrewakeOptions, Q as PrewakeResult, R as PrewakeStatus, S as QuicStreamDataTransport, U as RecordingBucket, V as RecordingLifecycle, W as RecordingStatus, Y as ReleaseSessionBeaconOptions, a2 as RuntimeAvailability, a3 as RuntimeWakeDetail, a4 as RuntimeWakeGolden, a5 as RuntimeWakeReasonCode, a6 as SIGNALING_PROTOCOL_VERSION, a7 as STREAM_END, aa as SessionDocument, af as SessionPhaseError, ai as SessionStatsOptions, am as SessionText, an as SignalCarrier, ao as Signaling, at as TransportEstablishedNotify, au as TransportNegotiator, av as TransportOfferRequest, az as TransportSessionSignaling, aB as VideoPlayoutOptions, aC as WT_CONTROL_FRAME_MAX, aD as WT_DATA_STREAM_VERSION, aE as WatchGenerationTickOptions, aH as WtControlDecoder, aI as WtControlMessage, aJ as WtDataEnvelope, aL as WtDataStreamParser, aP as consumeWtDataStreams, aS as decodeStreamEnvelope, aU as derivedLegName, aV as derivedLegRole, aW as encodeStreamEnvelope, aX as encodeWtControlFrame, aY as isPendingRecording, aZ as mediaRecorderChunkSource, a_ as parseDgramHeader, a$ as prewake, b0 as releaseSessionBeacon, b3 as watchGenerationTick, b4 as writeDgramHeader } from './stream-data-iemsO_1p.js';
|
|
3
3
|
import 'yjs';
|
|
4
4
|
import 'y-protocols/awareness';
|
|
5
5
|
|
|
@@ -1012,6 +1012,8 @@ declare class WebTransportSession implements MediaSession {
|
|
|
1012
1012
|
|
|
1013
1013
|
private decoderErrorsAt;
|
|
1014
1014
|
private writer;
|
|
1015
|
+
|
|
1016
|
+
private dgramWriter;
|
|
1015
1017
|
private deadCb;
|
|
1016
1018
|
private deadFired;
|
|
1017
1019
|
private stopped;
|
|
@@ -1055,6 +1057,10 @@ declare class WebTransportSession implements MediaSession {
|
|
|
1055
1057
|
start(): Promise<void>;
|
|
1056
1058
|
stop(): Promise<void>;
|
|
1057
1059
|
|
|
1060
|
+
private datagramWriter;
|
|
1061
|
+
|
|
1062
|
+
private releaseDatagramWriter;
|
|
1063
|
+
|
|
1058
1064
|
private dropUplinks;
|
|
1059
1065
|
onDead(cb: (reason: string) => void): void;
|
|
1060
1066
|
stats(): {
|