Skip to content

Commit 24b090c

Browse files
authored
Merge pull request microsoft#254544 from mjbvz/current-swordtail
Revert service-worker js -> ts rewrite
2 parents 9362739 + 5890e0a commit 24b090c

File tree

3 files changed

+124
-61
lines changed

3 files changed

+124
-61
lines changed

build/buildfile.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ exports.code = [
4444
createModuleDescription('vs/code/node/cliProcessMain'),
4545
createModuleDescription('vs/code/electron-utility/sharedProcess/sharedProcessMain'),
4646
createModuleDescription('vs/code/electron-browser/workbench/workbench'),
47-
createModuleDescription('vs/workbench/contrib/webview/browser/pre/service-worker')
4847
];
4948

5049
exports.codeWeb = createModuleDescription('vs/code/browser/workbench/workbench');

src/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@
3131
"./vs/**/*.ts",
3232
"./vscode-dts/vscode.proposed.*.d.ts",
3333
"./vscode-dts/vscode.d.ts"
34+
],
35+
"exclude": [
36+
"vs/workbench/contrib/webview/browser/pre/service-worker.js"
3437
]
3538
}

src/vs/workbench/contrib/webview/browser/pre/service-worker.ts renamed to src/vs/workbench/contrib/webview/browser/pre/service-worker.js

Lines changed: 121 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5+
//@ts-check
56
/// <reference lib="webworker" />
67

7-
const sw: ServiceWorkerGlobalScope = self as any as ServiceWorkerGlobalScope;
8+
/** @type {ServiceWorkerGlobalScope} */
9+
const sw = /** @type {any} */ (self);
810

911
const VERSION = 4;
1012

@@ -16,38 +18,54 @@ const searchParams = new URL(location.toString()).searchParams;
1618

1719
const remoteAuthority = searchParams.get('remoteAuthority');
1820

19-
let outerIframeMessagePort: MessagePort | undefined;
21+
/** @type {MessagePort|undefined} */
22+
let outerIframeMessagePort;
2023

2124
/**
2225
* Origin used for resources
2326
*/
2427
const resourceBaseAuthority = searchParams.get('vscode-resource-base-authority');
2528

29+
30+
/** @type {number} */
2631
const resolveTimeout = 30_000;
2732

28-
type RequestStoreResult<T> = {
29-
status: 'ok';
30-
value: T;
31-
} | {
32-
status: 'timeout';
33-
};
3433

35-
interface RequestStoreEntry<T> {
36-
resolve: (x: RequestStoreResult<T>) => void;
37-
promise: Promise<RequestStoreResult<T>>;
38-
}
34+
/**
35+
* @template T
36+
* @typedef {{ status: 'ok', value: T } | { status: 'timeout' }} RequestStoreResult
37+
*/
38+
39+
40+
/**
41+
* @template T
42+
* @typedef {{ resolve: (x: RequestStoreResult<T>) => void, promise: Promise<RequestStoreResult<T>> }} RequestStoreEntry
43+
*/
3944

40-
class RequestStore<T> {
41-
private map: Map<number, RequestStoreEntry<T>> = new Map();
42-
private requestPool: number = 0;
4345

44-
create(): { requestId: number; promise: Promise<RequestStoreResult<T>> } {
46+
/**
47+
* @template T
48+
*/
49+
class RequestStore {
50+
constructor() {
51+
/** @type {Map<number, RequestStoreEntry<T>>} */
52+
this.map = new Map();
53+
/** @type {number} */
54+
this.requestPool = 0;
55+
}
56+
57+
/**
58+
* @returns {{ requestId: number, promise: Promise<RequestStoreResult<T>> }}
59+
*/
60+
create() {
4561
const requestId = ++this.requestPool;
4662

47-
let resolve: (x: RequestStoreResult<T>) => void;
48-
const promise = new Promise<RequestStoreResult<T>>(r => resolve = r);
63+
/** @type {(x: RequestStoreResult<T>) => void} */
64+
let resolve;
65+
const promise = new Promise(r => resolve = r);
4966

50-
const entry: RequestStoreEntry<T> = { resolve: resolve!, promise };
67+
/** @type {RequestStoreEntry<T>} */
68+
const entry = { resolve, promise };
5169
this.map.set(requestId, entry);
5270

5371
const dispose = () => {
@@ -62,7 +80,12 @@ class RequestStore<T> {
6280
return { requestId, promise };
6381
}
6482

65-
resolve(requestId: number, result: T): boolean {
83+
/**
84+
* @param {number} requestId
85+
* @param {T} result
86+
* @returns {boolean}
87+
*/
88+
resolve(requestId, result) {
6689
const entry = this.map.get(requestId);
6790
if (!entry) {
6891
return false;
@@ -76,12 +99,14 @@ class RequestStore<T> {
7699
/**
77100
* Map of requested paths to responses.
78101
*/
79-
const resourceRequestStore = new RequestStore<ResourceResponse>();
102+
/** @type {RequestStore<ResourceResponse>} */
103+
const resourceRequestStore = new RequestStore();
80104

81105
/**
82106
* Map of requested localhost origins to optional redirects.
83107
*/
84-
const localhostRequestStore = new RequestStore<string | undefined>();
108+
/** @type {RequestStore<string|undefined>} */
109+
const localhostRequestStore = new RequestStore();
85110

86111
const unauthorized = () =>
87112
new Response('Unauthorized', { status: 401, });
@@ -95,12 +120,13 @@ const methodNotAllowed = () =>
95120
const requestTimeout = () =>
96121
new Response('Request Timeout', { status: 408, });
97122

98-
sw.addEventListener('message', async (event: ExtendableMessageEvent) => {
123+
sw.addEventListener('message', async (event) => {
99124
if (!event.source) {
100125
return;
101126
}
102127

103-
const source = event.source as Client;
128+
/** @type {Client} */
129+
const source = event.source;
104130
switch (event.data.channel) {
105131
case 'version': {
106132
outerIframeMessagePort = event.ports[0];
@@ -115,7 +141,8 @@ sw.addEventListener('message', async (event: ExtendableMessageEvent) => {
115141
return;
116142
}
117143
case 'did-load-resource': {
118-
const response = event.data.data as ResourceResponse;
144+
/** @type {ResourceResponse} */
145+
const response = event.data.data;
119146
if (!resourceRequestStore.resolve(response.id, response)) {
120147
console.log('Could not resolve unknown resource', response.path);
121148
}
@@ -135,7 +162,7 @@ sw.addEventListener('message', async (event: ExtendableMessageEvent) => {
135162
}
136163
});
137164

138-
sw.addEventListener('fetch', (event: FetchEvent) => {
165+
sw.addEventListener('fetch', (event) => {
139166
const requestUrl = new URL(event.request.url);
140167
if (typeof resourceBaseAuthority === 'string' && requestUrl.protocol === 'https:' && requestUrl.hostname.endsWith('.' + resourceBaseAuthority)) {
141168
switch (event.request.method) {
@@ -184,25 +211,32 @@ sw.addEventListener('fetch', (event: FetchEvent) => {
184211
}
185212
});
186213

187-
sw.addEventListener('install', (event: ExtendableEvent) => {
214+
sw.addEventListener('install', (event) => {
188215
event.waitUntil(sw.skipWaiting()); // Activate worker immediately
189216
});
190217

191-
sw.addEventListener('activate', (event: ExtendableEvent) => {
218+
sw.addEventListener('activate', (event) => {
192219
event.waitUntil(sw.clients.claim()); // Become available to all pages
193220
});
194221

195-
interface ResourceRequestUrlComponents {
196-
scheme: string;
197-
authority: string;
198-
path: string;
199-
query: string;
200-
}
201222

223+
/**
224+
* @typedef {Object} ResourceRequestUrlComponents
225+
* @property {string} scheme
226+
* @property {string} authority
227+
* @property {string} path
228+
* @property {string} query
229+
*/
230+
231+
/**
232+
* @param {FetchEvent} event
233+
* @param {ResourceRequestUrlComponents} requestUrlComponents
234+
* @returns {Promise<Response>}
235+
*/
202236
async function processResourceRequest(
203-
event: FetchEvent,
204-
requestUrlComponents: ResourceRequestUrlComponents
205-
): Promise<Response> {
237+
event,
238+
requestUrlComponents
239+
) {
206240
let client = await sw.clients.get(event.clientId);
207241
if (!client) {
208242
client = await getWorkerClientForId(event.clientId);
@@ -227,10 +261,12 @@ async function processResourceRequest(
227261

228262
const shouldTryCaching = (event.request.method === 'GET');
229263

230-
const resolveResourceEntry = (
231-
result: RequestStoreResult<ResourceResponse>,
232-
cachedResponse: Response | undefined
233-
): Response => {
264+
/**
265+
* @param {RequestStoreResult<ResourceResponse>} result
266+
* @param {Response|undefined} cachedResponse
267+
* @returns {Response}
268+
*/
269+
const resolveResourceEntry = (result, cachedResponse) => {
234270
if (result.status === 'timeout') {
235271
return requestTimeout();
236272
}
@@ -252,7 +288,8 @@ async function processResourceRequest(
252288
return notFound();
253289
}
254290

255-
const commonHeaders: Record<string, string> = {
291+
/** @type {Record<string, string>} */
292+
const commonHeaders = {
256293
'Access-Control-Allow-Origin': '*',
257294
};
258295

@@ -287,7 +324,8 @@ async function processResourceRequest(
287324
}
288325
}
289326

290-
const headers: Record<string, string> = {
327+
/** @type {Record<string, string>} */
328+
const headers = {
291329
...commonHeaders,
292330
'Content-Type': entry.mime,
293331
'Content-Length': byteLength.toString(),
@@ -312,7 +350,7 @@ async function processResourceRequest(
312350
headers['Cross-Origin-Opener-Policy'] = 'same-origin';
313351
}
314352

315-
const response = new Response(entry.data as Uint8Array<ArrayBuffer>, {
353+
const response = new Response(entry.data, {
316354
status: 200,
317355
headers
318356
});
@@ -325,7 +363,8 @@ async function processResourceRequest(
325363
return response.clone();
326364
};
327365

328-
let cached: Response | undefined;
366+
/** @type {Response|undefined} */
367+
let cached;
329368
if (shouldTryCaching) {
330369
const cache = await caches.open(resourceCacheName);
331370
cached = await cache.match(event.request);
@@ -366,10 +405,15 @@ async function processResourceRequest(
366405
return promise.then(entry => resolveResourceEntry(entry, cached));
367406
}
368407

408+
/**
409+
* @param {FetchEvent} event
410+
* @param {URL} requestUrl
411+
* @returns {Promise<Response>}
412+
*/
369413
async function processLocalhostRequest(
370-
event: FetchEvent,
371-
requestUrl: URL
372-
): Promise<Response> {
414+
event,
415+
requestUrl
416+
) {
373417
const client = await sw.clients.get(event.clientId);
374418
if (!client) {
375419
// This is expected when requesting resources on other localhost ports
@@ -390,9 +434,11 @@ async function processLocalhostRequest(
390434

391435
const origin = requestUrl.origin;
392436

393-
const resolveRedirect = async (
394-
result: RequestStoreResult<string | undefined>
395-
): Promise<Response> => {
437+
/**
438+
* @param {RequestStoreResult<string|undefined>} result
439+
* @returns {Promise<Response>}
440+
*/
441+
const resolveRedirect = async function (result) {
396442
if (result.status !== 'ok' || !result.value) {
397443
return fetch(event.request);
398444
}
@@ -432,12 +478,20 @@ async function processLocalhostRequest(
432478
return promise.then(resolveRedirect);
433479
}
434480

435-
function getWebviewIdForClient(client: Client): string | null {
481+
/**
482+
* @param {Client} client
483+
* @returns {string|null}
484+
*/
485+
function getWebviewIdForClient(client) {
436486
const requesterClientUrl = new URL(client.url);
437487
return requesterClientUrl.searchParams.get('id');
438488
}
439489

440-
async function getOuterIframeClient(webviewId: string): Promise<Client[]> {
490+
/**
491+
* @param {string} webviewId
492+
* @returns {Promise<Client[]>}
493+
*/
494+
async function getOuterIframeClient(webviewId) {
441495
const allClients = await sw.clients.matchAll({ includeUncontrolled: true });
442496
return allClients.filter(client => {
443497
const clientUrl = new URL(client.url);
@@ -446,7 +500,11 @@ async function getOuterIframeClient(webviewId: string): Promise<Client[]> {
446500
});
447501
}
448502

449-
async function getWorkerClientForId(clientId: string): Promise<Client | undefined> {
503+
/**
504+
* @param {string} clientId
505+
* @returns {Promise<Client|undefined>}
506+
*/
507+
async function getWorkerClientForId(clientId) {
450508
const allDedicatedWorkerClients = await sw.clients.matchAll({ type: 'worker' });
451509
const allSharedWorkerClients = await sw.clients.matchAll({ type: 'sharedworker' });
452510
const allWorkerClients = [...allDedicatedWorkerClients, ...allSharedWorkerClients];
@@ -455,9 +513,12 @@ async function getWorkerClientForId(clientId: string): Promise<Client | undefine
455513
});
456514
}
457515

458-
type ResourceResponse =
459-
| { readonly status: 200; id: number; path: string; mime: string; data: Uint8Array; etag: string | undefined; mtime: number | undefined }
460-
| { readonly status: 304; id: number; path: string; mime: string; mtime: number | undefined }
461-
| { readonly status: 401; id: number; path: string }
462-
| { readonly status: 404; id: number; path: string }
463-
;
516+
517+
/**
518+
* @typedef {(
519+
* | { readonly status: 200, id: number, path: string, mime: string, data: Uint8Array, etag: string|undefined, mtime: number|undefined }
520+
* | { readonly status: 304, id: number, path: string, mime: string, mtime: number|undefined }
521+
* | { readonly status: 401, id: number, path: string }
522+
* | { readonly status: 404, id: number, path: string }
523+
* )} ResourceResponse
524+
*/

0 commit comments

Comments
 (0)