-
-
Notifications
You must be signed in to change notification settings - Fork 65
fix: polyfill W3C compatibility #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
if (arguments.length === 0) throw new TypeError(`Failed to construct 'RTCDataChannelEvent': 2 arguments required, but only ${arguments.length} present.`) | ||
if (typeof init !== 'object') throw new TypeError("Failed to construct 'RTCDataChannelEvent': The provided value is not of type 'RTCDataChannelEventInit'.") | ||
if (!init.channel) throw new TypeError("Failed to construct 'RTCDataChannelEvent': Failed to read the 'channel' property from 'RTCDataChannelEventInit': Required member is undefined.") | ||
if (init.channel.constructor !== RTCDataChannel) throw new TypeError("Failed to construct 'RTCDataChannelEvent': Failed to read the 'channel' property from 'RTCDataChannelEventInit': Failed to convert value to 'RTCDataChannel'.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
required by spec
src/polyfill/RTCDataChannel.ts
Outdated
onclosing: globalThis.RTCDataChannel['onclosing']; | ||
onerror: globalThis.RTCDataChannel['onerror']; | ||
onmessage: globalThis.RTCDataChannel['onmessage']; | ||
onopen: globalThis.RTCDataChannel['onopen'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bettter to let the types define it, rather than manually declare any, a typed event target implementation would be prefered however
}); | ||
// we need updated connectionstate, so this is delayed by a single event loop tick | ||
// this is fucked and wonky, needs to be made better | ||
this.#dataChannel.onClosed(() => setTimeout(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the spec is very assine about how and when datachannels should close, this is the closest i was able to bring it inline with said spec, the order of events in peer, ice and dc on closing is important for some libraries
if (!ArrayBuffer.isView(message)) { | ||
data = message | ||
} else if (this.#binaryType === 'blob') { | ||
data = new Blob([message]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't explicitly use buffer, also cast to Blob when the type requires it, this wasn't even done before
this.#dataChannel.sendMessage(data); | ||
} else if (data instanceof Blob) { | ||
} else if ('arrayBuffer' in data) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we're not actually interested in blob, but its ab method, this is important for Blob-like libraries
state = 'closed'; | ||
} | ||
return state; | ||
if (this.#pc.connectionState === 'disconnected') return 'closed' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pc is always defined
@@ -58,7 +58,7 @@ export default class RTCIceCandidate implements globalThis.RTCIceCandidate { | |||
} | |||
|
|||
get address(): string | null { | |||
return this.#address || null; | |||
return this.#address ?? null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| was incorrect to use here!!! we want null checking, not falsy checking
}); | ||
} | ||
|
||
get component(): globalThis.RTCIceComponent { | ||
const cp = this.getSelectedCandidatePair(); | ||
if (!cp) return null; | ||
if (!cp?.local) return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didnt verify local!
src/polyfill/RTCIceTransport.ts
Outdated
getRemoteParameters(): any { | ||
/** */ | ||
getRemoteParameters(): RTCIceParameters | null { | ||
return new RTCIceParameters(new RTCIceCandidate({ candidate: this.#pc.getSelectedCandidatePair().remote.candidate, sdpMLineIndex: 0 })) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RTCIceParams were completely missing, these still dont have password/ufrag, need to wait for upstream to expose that
} | ||
|
||
get maxMessageSize(): number { | ||
if (this.state !== 'connected') return null; | ||
return this.#pc ? this.#extraFunctions.maxMessageSize() : 0; | ||
return this.#pc.maxMessageSize ?? 65536; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should never be 0
this.#type = init ? init.type : null; | ||
this.#sdp = init ? init.sdp : null; | ||
constructor(init: globalThis.RTCSessionDescriptionInit | null | undefined) { | ||
this.#type = init?.type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worked for the library, but not as a global exposed constructor
src/polyfill/RTCPeerConnection.ts
Outdated
// length of urls can not be 0 | ||
if (config.iceServers[i].urls?.length === 0) | ||
throw new exceptions.SyntaxError('IceServers urls cannot be empty'); | ||
setConfiguration(config: RTCConfiguration): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I for the most part removed the old implementation, because by default a lot of fallbacks are used, this is correct for W3C, but i'm not certain this is correct for NDC, this needs to be verified
}); | ||
|
||
this.#peerConnection.onLocalDescription((sdp, type) => { | ||
if (type === 'offer') { | ||
this.#localOffer.resolve({ sdp, type }); | ||
this.#localOffer.resolve(new RTCSessionDescription({ sdp, type })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was incorrect!
this.ontrack?.(e as RTCTrackEvent) | ||
}) | ||
|
||
this.addEventListener('negotiationneeded', e => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was never implemented, and is required for polite-peer libs
} | ||
|
||
createOffer(): Promise<globalThis.RTCSessionDescriptionInit | any> { | ||
createOffer(): Promise<globalThis.RTCSessionDescriptionInit> & Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are some annoying deprecated overloads for some of these methods, we shouldn't support them
Hello and thank you for the PR. I think it will be good in all cases to separate this PR into small PRs. Especially RTCRtp part.
|
I assumed you use some manual commands, because rollup isn't even installable as you include a package-lock, and removing it, causes version conflict errors, so I couldn't even run rollup to try compiling it |
you can feel free to split up this PR, I kinda lost my will to live after implementing the video/audio track shenanigans, mainly because of how they are exposed, I think the bindings need to do it a bit better than what we currently have, but that's honestly above what I'm willing to do, so I tried somewhat finishing it, even tho I don't think it actually works correctly as I couldn't find how to properly create and consume tracks and transceivers |
I didn't understand what you mean. for others you can check |
Unfortunately, I can not split the PR. About the tracks, we need definitely a separate PR and work and of course some test cases. |
@murat-dogan are you gonna look at this? |
Hi @ThaUnknown, Actually, I am waiting for you.
|
waiting for what....? you said that tracks should be a separate PR, I removed them and there was no follow up from you, if I update the PR the same thing will happen....? |
I have clearly said here
You said
And I said
If you try to push uncompilable changes, yes unfortunately the same thing will happen, otherwise for me no problem. I think the best way will be to create small and separate PRs. |
yes, which was all fixed by 03ac9d3 which simply nuked the things that prevented it from compiling, the changes were compatible at the time they were made, simply no follow ups on the PR made it outdated which is why i'm asking, "what was wrong here" because there's 0 reason for me to update a PR which will just be left to sit again, with no reason as to why that happens |
That has no meaning. For me definitely no problem. |
okay, I don't think we're... understanding eachother here's what I mean:
I'm asking why there was no follow up, did you simply forget, or was there still something wrong with the PR, if I update the PR will it be left hanging again with no reason given? |
No, I didn't forget it. I was so complex to handle in one go, even after the changes. As I said this conversation has no meaning. |
which brings me back to the whole "will you look at this" this PR is not even remotely complex, 95% of it is just correctly declaring types which was also pointed out in #346, fixing error naming to be inline with W3C spec, and fixing nullish coalescing as the logical OR operator was used in many places incorrectly this PR only actually has 3 functional changes:
|
I don't really know what to say. Build gives error
test gives error
wpt tests give error
|
fix: stricter type definitions
I think the main reason for this PR is fixing more compatibility issues, so we can pass more tests right? Please note that I don't know why but there is a problem with the "'/webrtc/no-media-call.html'," test Also, tests still fail. |
build now works, i was still in the progress of fixing it when u sent that npm run test isnt runnable on windows, I assume you're running linux same as above also IIRC wpt tests require a network hosts setup, which is not included in the commands |
Yes, I am using Linux. Please see here for Linux instructions, Since I am not running on windows I can not tell commands for windows to setup the hosts. You can run this to run the server
In another terminal you can run the tests
And this is exactly why I am saying we should go with small PRs. |
the PR could be 1 line of code, it doesn't change that the problems are with the commands and test suite, not the PR, we're not even getting to the "run code part" here |
welp I don't have the time to fix the native code for this today, i'll have to re-visit this later, since the changes that were made in the past 3 months broke the PR, which causes NAPI to exit the entire process, and jest refuses to log when that happens, woeful |
fix: cross-os env definitions fix: WAY stricter type defs fix: imports
Just wanted to jump in here to clear the air a bit and help us move forward. @murat-dogan @ThaUnknown I believe this PR is still important. It fixes a bunch of subtle but real issues, like spec compliance, proper typing, event ordering, and buffer handling — all things that improve stability and help us get closer to passing more WPTs. @achingbrain already split some parts off, thanks for that, but they still haven’t been merged. Let’s make things easier for everyone and done the remaining parts. |
if you want to have this merged they badly, you've seen the discussion, simply try to get wpt to work and contribute the changes |
@ThaUnknown |
oh sorry, I didn't mean you, I meant the guy above us who's rushing us, while contributing nothing those PR's are already crated, you linked them...? also please diff the files in |
@ThaUnknown You’re saying I haven’t contributed anything, but what exactly am I supposed to do on top of an existing complex PR? Instead of arguing endlessly, I told you to just structure the PR the way Murat asked — which, by the way, is the correct approach. Here’s an example of how a PR should be made: And here’s a clear example of how discussion should be handled properly: Hope you take something from it. |
Yes, I also understood correctly, that you are saying it to @mertushka Since you said I made also these changes, I said to create a PR for #347 and #348, in order to not block the other things. I don't think it is a good idea to merge this PR like this. I am trying to be polite, but I don't think we are a good match. I guess it will be better to do what you said before.
|
yeah I... agree.... my tone is very.... passive aggressive I guess? people tend to not like that, but I don't like mincing words because it leads to miscommunication, for which I often don't have the time
you and me both, trust me, I'm running my own fork of this library, so I wanted to contribute all the fixes I've applied to it, which is a dependency of another library I maintain, which is a dependency of another library I maintain, which is a dependency of another library I maintain, which is a dependency of another lib I maintain [not even joking ndc fork -> simple-peer -> bt-tracker -> torrent-discovery -> webtorrent, FOSS is hell!], which is then used by a bunch of my apps, all of which have a lot of their own "only in the world" solutions and dependencies too That's why I was so unwilling to split this PR, because it's a lot of work, which for me feels unnecessary and is a waste of time I already don't have.
yeah, I documented all the changes in the reviews, so you should have no problem finding what problems they solve, feel free to close this PR and use it as a reference in the future, I never got pre-negotiated data channels working, neither in your lib, or mine so there's something fun for you to poke at too haha |
this PR aims to fix all the critical W3C compatibility issues in the polyfill
it also implements rudimentary MediaStreams [WIP]
I'll add comments to the PR explaining things