1
- /** @type {Set<{ numberOfProcessedImages: number, imagesToDownload: string[], options: any, next: () => void }> } */
1
+ // @ts -check
2
+ /** @typedef {{ numberOfProcessedImages: number, imagesToDownload: string[], options: any, next: () => void } } Task */
3
+
4
+ /** @type {Set<Task> } */
2
5
const tasks = new Set ( ) ;
3
6
4
- // NOTE: Don't directly use an `async` function as a listener:
5
- // https://stackoverflow.com/a/56483156
6
7
chrome . runtime . onMessage . addListener ( startDownload ) ;
7
8
chrome . downloads . onDeterminingFilename . addListener ( suggestNewFilename ) ;
8
9
9
- function startDownload ( message , sender , resolve ) {
10
- if ( message ?. type !== 'downloadImages' ) return ;
10
+ // NOTE: Don't directly use an `async` function as a listener for `onMessage`:
11
+ // https://stackoverflow.com/a/56483156
12
+ // https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessage
13
+ function startDownload (
14
+ /** @type {any } */ message ,
15
+ /** @type {chrome.runtime.MessageSender } */ sender ,
16
+ /** @type {(response?: any) => void } */ resolve
17
+ ) {
18
+ if ( ! ( message && message . type === 'downloadImages' ) ) return ;
11
19
12
20
downloadImages ( {
13
21
numberOfProcessedImages : 0 ,
@@ -21,22 +29,24 @@ function startDownload(message, sender, resolve) {
21
29
} ,
22
30
} ) . then ( resolve ) ;
23
31
24
- return true ;
32
+ return true ; // Keeps the message channel open until `resolve` is called
25
33
}
26
34
27
- async function downloadImages ( task ) {
35
+ async function downloadImages ( /** @type { Task } */ task ) {
28
36
tasks . add ( task ) ;
29
37
for ( const image of task . imagesToDownload ) {
30
38
await new Promise ( ( resolve ) => {
31
39
chrome . downloads . download ( { url : image } , resolve ) ;
32
40
} ) ;
33
41
if ( chrome . runtime . lastError ) {
34
42
console . error ( `${ chrome . runtime . lastError . message } : ${ image } ` ) ;
35
- task . next ( ) ;
36
43
}
44
+ task . next ( ) ;
37
45
}
38
46
}
39
47
48
+ // https://developer.chrome.com/docs/extensions/reference/downloads/#event-onDeterminingFilename
49
+ /** @type {Parameters<chrome.downloads.DownloadDeterminingFilenameEvent['addListener']>[0] } */
40
50
function suggestNewFilename ( item , suggest ) {
41
51
const task = [ ...tasks ] [ 0 ] ;
42
52
if ( ! task ) {
@@ -62,7 +72,6 @@ function suggestNewFilename(item, suggest) {
62
72
}
63
73
64
74
suggest ( { filename : normalizeSlashes ( newFilename ) } ) ;
65
- task . next ( ) ;
66
75
}
67
76
68
77
function normalizeSlashes ( filename ) {
0 commit comments