diff --git a/src/workerd/api/events.c++ b/src/workerd/api/events.c++ index 744af834f33..34e18b57beb 100644 --- a/src/workerd/api/events.c++ +++ b/src/workerd/api/events.c++ @@ -72,7 +72,7 @@ MessageEvent::MessageEvent(jsg::Lock& js, kj::String type, Initializer initializ }), data(kj::mv(initializer.data).orDefault([&] { return jsg::JsRef(js, js.null()); })), lastEventId(kj::mv(initializer.lastEventId).orDefault(kj::String())), - maybeSource(kj::mv(initializer.source)), + maybeSource(kj::mv(initializer.source).orDefault(kj::none)), // Per the spec, origin defaults to the empty string for user-constructed events. maybeOrigin(kj::mv(initializer.origin) .map([](jsg::USVString&& origin) -> kj::String { return kj::mv(origin); }) diff --git a/src/workerd/api/events.h b/src/workerd/api/events.h index 07f7956a561..7eea774a62f 100644 --- a/src/workerd/api/events.h +++ b/src/workerd/api/events.h @@ -52,7 +52,7 @@ class MessageEvent final: public Event { jsg::Optional> data; jsg::Optional origin; jsg::Optional lastEventId; - jsg::Optional> source; + jsg::Optional>> source; jsg::Optional>> ports; JSG_STRUCT(bubbles, cancelable, composed, data, origin, lastEventId, source, ports); diff --git a/src/workerd/api/tests/events-test.js b/src/workerd/api/tests/events-test.js index c2d53a1bb96..d83eb006ddd 100644 --- a/src/workerd/api/tests/events-test.js +++ b/src/workerd/api/tests/events-test.js @@ -782,6 +782,43 @@ export const messageEventSpecInit = { }, }; +// MessageEventInit's source is nullable, so an event whose source reads as null can +// serve as the init for a new event. +export const messageEventNullSource = { + async test() { + strictEqual(new MessageEvent('message', { source: null }).source, null); + + const original = new MessageEvent('message', { + data: 'x', + lastEventId: '7', + }); + const copy = new MessageEvent(original.type, original); + strictEqual(copy.data, 'x'); + strictEqual(copy.lastEventId, '7'); + strictEqual(copy.source, null); + + // Message events fired by a WebSocket have a null source as well. + const { 0: client, 1: server } = new WebSocketPair(); + client.accept(); + server.accept(); + const { promise, resolve, reject } = Promise.withResolvers(); + client.addEventListener('message', (event) => { + try { + resolve(new MessageEvent(event.type, event)); + } catch (err) { + reject(err); + } + }); + server.send('hello'); + const cloned = await promise; + strictEqual(cloned.data, 'hello'); + strictEqual(cloned.source, null); + + client.close(); + server.close(); + }, +}; + // CloseEventInit supports the common EventInit members. export const closeEventSpecInit = { test() { diff --git a/types/generated-snapshot/experimental/index.d.ts b/types/generated-snapshot/experimental/index.d.ts index 867c301208b..3bd84f5ac64 100755 --- a/types/generated-snapshot/experimental/index.d.ts +++ b/types/generated-snapshot/experimental/index.d.ts @@ -1752,7 +1752,7 @@ interface MessageEventInit { data?: any; origin?: string; lastEventId?: string; - source?: MessagePort; + source?: MessagePort | null; ports?: MessagePort[]; } /** diff --git a/types/generated-snapshot/experimental/index.ts b/types/generated-snapshot/experimental/index.ts index b4b45c6911e..58ce62d643a 100755 --- a/types/generated-snapshot/experimental/index.ts +++ b/types/generated-snapshot/experimental/index.ts @@ -1756,7 +1756,7 @@ export interface MessageEventInit { data?: any; origin?: string; lastEventId?: string; - source?: MessagePort; + source?: MessagePort | null; ports?: MessagePort[]; } /** diff --git a/types/generated-snapshot/index.d.ts b/types/generated-snapshot/index.d.ts index bf045f65615..aab5bb0dabc 100755 --- a/types/generated-snapshot/index.d.ts +++ b/types/generated-snapshot/index.d.ts @@ -1726,7 +1726,7 @@ interface MessageEventInit { data?: any; origin?: string; lastEventId?: string; - source?: MessagePort; + source?: MessagePort | null; ports?: MessagePort[]; } /** diff --git a/types/generated-snapshot/index.ts b/types/generated-snapshot/index.ts index bf91bddca5a..f0c25c20e72 100755 --- a/types/generated-snapshot/index.ts +++ b/types/generated-snapshot/index.ts @@ -1730,7 +1730,7 @@ export interface MessageEventInit { data?: any; origin?: string; lastEventId?: string; - source?: MessagePort; + source?: MessagePort | null; ports?: MessagePort[]; } /**