-
Notifications
You must be signed in to change notification settings - Fork 2
/
listen.ts
121 lines (104 loc) · 3.75 KB
/
listen.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import * as flags from "https://deno.land/std/flags/mod.ts";
class AdaptedFetchEvent extends Event implements FetchEvent {
#event: Deno.RequestEvent;
constructor(type: string, eventInitDict?: FetchEventInit);
constructor(event: Deno.RequestEvent);
constructor(event: string | Deno.RequestEvent) {
super('fetch');
if (typeof event === 'string') throw Error('Overload not implemented');
this.#event = event;
}
get request(): Request { return this.#event.request };
respondWith(r: Response | Promise<Response>): void {
this.#event.respondWith(r);
}
waitUntil(_f: any): void {
// Deno doesn't shut down the way Service Workers or CF Workers do, so this is a noop.
}
get clientId(): string { return '' };
get preloadResponse(): Promise<any> { return Promise.resolve() };
get replacesClientId(): string { return '' };
get resultingClientId(): string { return '' };
}
// TODO: Don't overwrite if already present?
Object.defineProperty(self, 'FetchEvent', {
configurable: false,
enumerable: false,
writable: false,
value: AdaptedFetchEvent,
});
; (async () => {
let server: Deno.Listener;
if (self.location.protocol === 'https:' || self.location.port === '433') {
const { c, cert, k, key } = flags.parse(Deno.args);
const certFile = cert || c;
const keyFile = key || k;
if (!certFile || !keyFile) {
console.warn('When using HTTPS or port 443, a --cert and --key are required.');
}
server = Deno.listenTls({
hostname: self.location.hostname,
port: Number(self.location.port || 443),
certFile,
keyFile,
});
} else {
server = Deno.listen({
hostname: self.location.hostname,
port: Number(self.location.port || 80),
});
}
for await (const conn of server) {
(async () => {
for await (const event of Deno.serveHttp(conn)) {
// (<any>event.request).deno = {};
// (<any>event.request).deno['connecting-ip'] = (<Deno.NetAddr>conn.remoteAddr).hostname;
self.dispatchEvent(new AdaptedFetchEvent(event));
}
})();
}
})();
declare global {
/**
* Extends the lifetime of the install and activate events dispatched on the global scope as part of the
* service worker lifecycle. This ensures that any functional events (like FetchEvent) are not dispatched until it
* upgrades database schemas and deletes the outdated cache entries.
*/
interface ExtendableEvent extends Event {
waitUntil(f: any): void;
}
interface ExtendableEventInit extends EventInit {
}
var ExtendableEvent: {
prototype: ExtendableEvent;
new(type: string, eventInitDict?: ExtendableEventInit): ExtendableEvent;
};
interface FetchEventInit extends ExtendableEventInit {
clientId?: string;
preloadResponse?: Promise<any>;
replacesClientId?: string;
request: Request;
resultingClientId?: string;
}
var FetchEvent: {
prototype: FetchEvent;
new(type: string, eventInitDict: FetchEventInit): FetchEvent;
};
/**
* This is the event type for fetch events dispatched on the service worker global scope.
* It contains information about the fetch, including the request and how the receiver will treat the response.
* It provides the event.respondWith() method, which allows us to provide a response to this fetch.
*/
interface FetchEvent extends ExtendableEvent {
readonly clientId: string;
readonly preloadResponse: Promise<any>;
readonly replacesClientId: string;
readonly request: Request;
readonly resultingClientId: string;
respondWith(r: Response | Promise<Response>): void;
}
interface Window {
FetchEvent: new (type: string, eventInitDict: FetchEventInit) => FetchEvent;
}
function addEventListener(type: 'fetch', handler: (event: FetchEvent) => void): void;
}