Skip to content
File

Blob: src/workerd/api/events.h

cpp183 lines
1#pragma once
2 
3#include "basics.h"
4 
5#include <workerd/api/messagechannel.h>
6#include <workerd/jsg/jsg.h>
7#include <workerd/jsg/url.h>
8 
9namespace workerd::api {
10 
11class Blob;
12 
13class MessageEvent final: public Event {
14 public:
15 MessageEvent(jsg::Lock& js,
16 const jsg::JsValue& data,
17 kj::String lastEventId = kj::String(),
18 kj::Maybe<jsg::Ref<MessagePort>> source = kj::none,
19 kj::Maybe<jsg::Url&> urlForOrigin = kj::none);
20 
21 MessageEvent(jsg::Lock& js,
22 jsg::JsRef<jsg::JsValue> data,
23 kj::String lastEventId = kj::String(),
24 kj::Maybe<jsg::Ref<MessagePort>> source = kj::none,
25 kj::Maybe<jsg::Url&> urlForOrigin = kj::none);
26 
27 MessageEvent(jsg::Lock& js,
28 kj::String type,
29 const jsg::JsValue& data,
30 kj::String lastEventId = kj::String(),
31 kj::Maybe<jsg::Ref<MessagePort>> source = kj::none,
32 kj::Maybe<jsg::Url&> urlForOrigin = kj::none);
33 
34 MessageEvent(jsg::Lock& js,
35 kj::String type,
36 kj::OneOf<jsg::JsRef<jsg::JsValue>, jsg::Ref<Blob>> data,
37 kj::String lastEventId = kj::String(),
38 kj::Maybe<jsg::Ref<MessagePort>> source = kj::none,
39 kj::Maybe<jsg::Url&> urlForOrigin = kj::none);
40 
41 struct Initializer {
42 jsg::JsRef<jsg::JsValue> data;
43 
44 JSG_STRUCT(data);
45 JSG_STRUCT_TS_OVERRIDE(MessageEventInit {
46 data: ArrayBuffer | string;
47 });
48 };
49 static jsg::Ref<MessageEvent> constructor(
50 jsg::Lock& js, kj::String type, Initializer initializer);
51 
52 kj::OneOf<jsg::JsValue, jsg::Ref<Blob>> getData(jsg::Lock& js);
53 
54 kj::Maybe<kj::ArrayPtr<const char>> getOrigin();
55 
56 kj::StringPtr getLastEventId();
57 
58 // Per the spec, the source of a MessageEvent is one of a MessagePort,
59 // ServiceWorker, WindowProxy, etc. The only one of these we actually
60 // support is MessagePort, return that if its set or null if not.
61 kj::Maybe<jsg::Ref<MessagePort>> getSource();
62 
63 kj::ArrayPtr<jsg::Ref<MessagePort>> getPorts();
64 
65 JSG_RESOURCE_TYPE(MessageEvent) {
66 JSG_INHERIT(Event);
67 
68 JSG_READONLY_INSTANCE_PROPERTY(data, getData);
69 JSG_READONLY_INSTANCE_PROPERTY(origin, getOrigin);
70 JSG_READONLY_INSTANCE_PROPERTY(lastEventId, getLastEventId);
71 JSG_READONLY_INSTANCE_PROPERTY(source, getSource);
72 JSG_READONLY_INSTANCE_PROPERTY(ports, getPorts);
73 
74 JSG_TS_ROOT();
75 JSG_TS_OVERRIDE({ readonly data: any; });
76 }
77 
78 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const;
79 
80 private:
81 // Blob is used only by web-socket.h/c++
82 kj::OneOf<jsg::JsRef<jsg::JsValue>, jsg::Ref<Blob>> data;
83 kj::String lastEventId;
84 kj::Maybe<jsg::Ref<MessagePort>> maybeSource;
85 kj::Maybe<kj::Array<const char>> maybeOrigin;
86 
87 void visitForGc(jsg::GcVisitor& visitor);
88};
89 
90class OpenEvent final: public Event {
91 public:
92 OpenEvent(): Event("open"_kjc) {}
93 static jsg::Ref<OpenEvent> constructor() = delete;
94 JSG_RESOURCE_TYPE(OpenEvent) {
95 JSG_INHERIT(Event);
96 }
97};
98 
99class ErrorEvent: public Event {
100 public:
101 struct ErrorEventInit {
102 jsg::Optional<kj::String> message;
103 jsg::Optional<kj::String> filename;
104 jsg::Optional<int32_t> lineno;
105 jsg::Optional<int32_t> colno;
106 jsg::Optional<jsg::JsRef<jsg::JsValue>> error;
107 JSG_STRUCT(message, filename, lineno, colno, error);
108 };
109 
110 ErrorEvent(ErrorEventInit init);
111 ErrorEvent(kj::String type, ErrorEventInit init);
112 ErrorEvent(jsg::Lock& js, jsg::JsValue error);
113 
114 static jsg::Ref<ErrorEvent> constructor(
115 jsg::Lock& js, kj::String type, jsg::Optional<ErrorEventInit> init);
116 
117 kj::StringPtr getFilename();
118 kj::StringPtr getMessage();
119 int getLineno();
120 int getColno();
121 jsg::JsValue getError(jsg::Lock& js);
122 
123 JSG_RESOURCE_TYPE(ErrorEvent) {
124 JSG_INHERIT(Event);
125 
126 JSG_READONLY_PROTOTYPE_PROPERTY(filename, getFilename);
127 JSG_READONLY_PROTOTYPE_PROPERTY(message, getMessage);
128 JSG_READONLY_PROTOTYPE_PROPERTY(lineno, getLineno);
129 JSG_READONLY_PROTOTYPE_PROPERTY(colno, getColno);
130 JSG_READONLY_PROTOTYPE_PROPERTY(error, getError);
131 
132 JSG_TS_ROOT();
133 }
134 
135 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const;
136 
137 private:
138 ErrorEventInit init;
139 
140 void visitForGc(jsg::GcVisitor& visitor);
141};
142 
143// ======================================================================================
144class PromiseRejectionEvent: public Event {
145 public:
146 PromiseRejectionEvent(
147 v8::PromiseRejectEvent type, jsg::V8Ref<v8::Promise> promise, jsg::Value reason);
148 
149 static jsg::Ref<PromiseRejectionEvent> constructor(kj::String type) = delete;
150 
151 jsg::V8Ref<v8::Promise> getPromise(jsg::Lock& js) {
152 return promise.addRef(js);
153 }
154 jsg::Value getReason(jsg::Lock& js) {
155 return reason.addRef(js);
156 }
157 
158 JSG_RESOURCE_TYPE(PromiseRejectionEvent) {
159 JSG_INHERIT(Event);
160 JSG_READONLY_INSTANCE_PROPERTY(promise, getPromise);
161 JSG_READONLY_INSTANCE_PROPERTY(reason, getReason);
162 }
163 
164 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const {
165 tracker.trackField("promise", promise);
166 tracker.trackField("reason", reason);
167 }
168 
169 private:
170 jsg::V8Ref<v8::Promise> promise;
171 jsg::Value reason;
172 
173 void visitForGc(jsg::GcVisitor& visitor) {
174 visitor.visit(promise, reason);
175 }
176};
177 
178#define EW_EVENTS_ISOLATE_TYPES \
179 api::ErrorEvent, api::ErrorEvent::ErrorEventInit, api::MessageEvent, \
180 api::MessageEvent::Initializer, api::PromiseRejectionEvent, api::OpenEvent
181 
182} // namespace workerd::api