-
Notifications
You must be signed in to change notification settings - Fork 331
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
implement MessagePort and MessageChannel #3336
base: main
Are you sure you want to change the base?
Conversation
The generated output of Full Type Diff |
0444359
to
5c3d7b1
Compare
No idea how all the comments got marked resolved. Very weird. |
5c3d7b1
to
34e78d5
Compare
kj::Maybe<jsg::HashableV8Ref<v8::Object>> onmessageerror; | ||
|
||
// Each MessagePort object can be entangled with another (a symmetric relationship) | ||
kj::Maybe<jsg::Ref<MessagePort>> entangledWith{}; |
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.
You'll need the visitForGc
method implemented in this class also visiting each of these fields (onmessage
, onmessageerror
, and entagledWith
)
34e78d5
to
e66571f
Compare
public: | ||
CloseEvent(): Event("close") {} | ||
|
||
CloseEvent(uint code, kj::String reason, bool clean) |
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.
It's worth adding code comments here indicating that these constructor variations are specific to websockets.
static jsg::Ref<MessagePort> constructor(); | ||
|
||
struct StructuredSerializeOptions { | ||
kj::Array<jsg::Object> transfer{}; |
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.
jsg::Object
instances must always be held by a jsg::Ref
... this should also be an optional argument also.
kj::Array<jsg::Object> transfer{}; | |
jsg::Optional<kj::Array<jsg::Ref<jsg::Object>>> transfer{}; |
|
||
void postMessage(jsg::Lock& js, | ||
jsg::Value message, | ||
kj::OneOf<kj::Maybe<StructuredSerializeOptions>, kj::Array<jsg::Value>> options); |
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 should be inverted and made into a jsg::Optional
...
jsg::Optional<kj::OneOf<StructuredSerializeOptions, kj::Array<jsg::Value>> options
~MessagePort() noexcept(false); | ||
KJ_DISALLOW_COPY(MessagePort); | ||
|
||
static jsg::Ref<MessagePort> constructor(); |
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.
Per the spec, new MessagePort()
should fail with an error (it is not user constructible). This should be removed.
static jsg::Ref<MessagePort> constructor(); |
MessageChannel::MessageChannel(jsg::Lock &js) | ||
: port1(MessagePort::constructor()), | ||
port2(MessagePort::constructor()) {} |
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.
MessageChannel::MessageChannel(jsg::Lock &js) | |
: port1(MessagePort::constructor()), | |
port2(MessagePort::constructor()) {} | |
MessageChannel::MessageChannel(jsg::Lock &js) | |
: port1(jsg::alloc<MessagePort>()), | |
port2(jsg::alloc<MessagePort>()) {} |
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.
These should be entangled with each other immediately after creation, shouldn't they?
jsg::Ref<MessagePort> MessagePort::constructor() { | ||
return jsg::alloc<MessagePort>(); | ||
} |
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.
MessagePort is not user-constructible so shouldn't implement this
jsg::Ref<MessagePort> MessagePort::constructor() { | |
return jsg::alloc<MessagePort>(); | |
} |
void MessagePort::disentangle(jsg::Lock &js) { | ||
KJ_IF_SOME(e, entangledWith) { | ||
// Fire an event named close at otherPort. | ||
e->dispatchEvent(js, CloseEvent::constructor()); |
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.
In general practice, the static constructor is meant to the be implementation of the new T
constructor in javascript. For internal construction, use jsg::alloc<T>
instead.
e->dispatchEvent(js, CloseEvent::constructor()); | |
e->dispatchEvent(js, jsg::alloc<CloseEvent>()); |
// If this is entangled, disentangle it. | ||
disentangle(js); | ||
// The close event will be fired even if the port is not explicitly closed. | ||
dispatchEvent(js, CloseEvent::constructor()); |
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.
dispatchEvent(js, CloseEvent::constructor()); | |
dispatchEvent(js, jsg::alloc<CloseEvent>()); |
void close(jsg::Lock& js); | ||
|
||
JSG_RESOURCE_TYPE(MessagePort) { | ||
JSG_NESTED_TYPE(EventTarget); |
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.
JSG_NESTED_TYPE(EventTarget); | |
JSG_INHERIT(EventTarget) |
JSG_READONLY_PROTOTYPE_PROPERTY(port1, getPort1); | ||
JSG_READONLY_PROTOTYPE_PROPERTY(port2, getPort2); |
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.
Does the spec require these to be properties on the MessageChannel
prototype? If not, using lazy instance properties would be more efficient. Not critical tho.
JSG_READONLY_PROTOTYPE_PROPERTY(port1, getPort1); | |
JSG_READONLY_PROTOTYPE_PROPERTY(port2, getPort2); | |
JSG_READONLY_LAZY_INSTANCE_PROPERTY(port1, getPort1); | |
JSG_READONLY_LAZY_INSTANCE_PROPERTY(port2, getPort2); |
// Ref: https://html.spec.whatwg.org/multipage/web-messaging.html#message-channels | ||
class MessageChannel: public jsg::Object { | ||
public: | ||
explicit MessageChannel(jsg::Lock& js); |
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 jsg::Lock&
argument is not used.
Fixes #3273