| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | const Template = require("../Template"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | class FetchCompileWasmMainTemplatePlugin { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	apply(mainTemplate) { | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		mainTemplate.hooks.localVars.tap("FetchCompileWasmMainTemplatePlugin", (source, chunk) => { | 
					
						
							| 
									
										
										
										
											2017-11-21 19:57:40 +08:00
										 |  |  | 			if(!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) | 
					
						
							|  |  |  | 				return source; | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 			return Template.asString([ | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				source, | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				"// object to store loaded and loading wasm modules", | 
					
						
							|  |  |  | 				"var installedWasmModules = {};", | 
					
						
							|  |  |  | 			]); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		mainTemplate.hooks.requireEnsure.tap("FetchCompileWasmMainTemplatePlugin", (source, chunk, hash) => { | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 			const webassemblyModuleFilename = mainTemplate.outputOptions.webassemblyModuleFilename; | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			const chunkModuleMaps = chunk.getChunkModuleMaps(false, m => m.type.startsWith("webassembly")); | 
					
						
							|  |  |  | 			if(Object.keys(chunkModuleMaps.id).length === 0) return source; | 
					
						
							| 
									
										
										
										
											2017-11-29 01:43:01 +08:00
										 |  |  | 			const wasmModuleSrcPath = mainTemplate.getAssetPath(JSON.stringify(webassemblyModuleFilename), { | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 				hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, | 
					
						
							|  |  |  | 				hashWithLength: length => `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				module: { | 
					
						
							|  |  |  | 					id: "\" + wasmModuleId + \"", | 
					
						
							|  |  |  | 					hash: `" + ${JSON.stringify(chunkModuleMaps.hash)}[wasmModuleId] + "`, | 
					
						
							|  |  |  | 					hashWithLength(length) { | 
					
						
							|  |  |  | 						const shortChunkHashMap = Object.create(null); | 
					
						
							|  |  |  | 						Object.keys(chunkModuleMaps.hash).forEach(wasmModuleId => { | 
					
						
							|  |  |  | 							if(typeof chunkModuleMaps.hash[wasmModuleId] === "string") | 
					
						
							|  |  |  | 								shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[wasmModuleId].substr(0, length); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						return `" + ${JSON.stringify(shortChunkHashMap)}[wasmModuleId] + "`; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 			return Template.asString([ | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				source, | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				"// Fetch + compile chunk loading for webassembly", | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				`var wasmModules = ${JSON.stringify(chunkModuleMaps.id)}[chunkId] || [];`, | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				"wasmModules.forEach(function(wasmModuleId) {", | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 				Template.indent([ | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 					"var installedWasmModuleData = installedWasmModules[wasmModuleId];", | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					"// a Promise means \"currently loading\" or \"already loaded\".", | 
					
						
							| 
									
										
										
										
											2017-11-03 16:44:43 +08:00
										 |  |  | 					"promises.push(installedWasmModuleData ||", | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 					Template.indent([ | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 						`(installedWasmModules[wasmModuleId] = fetch(${mainTemplate.requireFn}.p + ${wasmModuleSrcPath}).then(function(response) {`, | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 						Template.indent([ | 
					
						
							| 
									
										
										
										
											2017-11-03 16:44:43 +08:00
										 |  |  | 							"if(WebAssembly.compileStreaming) {", | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 							Template.indent([ | 
					
						
							| 
									
										
										
										
											2017-11-03 16:44:43 +08:00
										 |  |  | 								"return WebAssembly.compileStreaming(response);" | 
					
						
							|  |  |  | 							]), | 
					
						
							|  |  |  | 							"} else {", | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 							Template.indent([ | 
					
						
							| 
									
										
										
										
											2017-11-03 16:44:43 +08:00
										 |  |  | 								"return response.arrayBuffer().then(function(bytes) { return WebAssembly.compile(bytes); });", | 
					
						
							|  |  |  | 							]), | 
					
						
							|  |  |  | 							"}" | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 						]), | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 						`}).then(function(module) { ${mainTemplate.requireFn}.w[wasmModuleId] = module; }))` | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 					]), | 
					
						
							| 
									
										
										
										
											2017-11-03 16:44:43 +08:00
										 |  |  | 					");", | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				]), | 
					
						
							|  |  |  | 				"});", | 
					
						
							|  |  |  | 			]); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		mainTemplate.hooks.requireExtensions.tap("FetchCompileWasmMainTemplatePlugin", (source, chunk) => { | 
					
						
							| 
									
										
										
										
											2017-11-21 19:57:40 +08:00
										 |  |  | 			if(!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) | 
					
						
							|  |  |  | 				return source; | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 			return Template.asString([ | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 				source, | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				"// object with all compiled WebAssmbly.Modules", | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 				`${mainTemplate.requireFn}.w = {};` | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 			]); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-14 04:35:39 +08:00
										 |  |  | 		mainTemplate.hooks.hash.tap("FetchCompileWasmMainTemplatePlugin", hash => { | 
					
						
							| 
									
										
										
										
											2017-11-12 01:48:29 +08:00
										 |  |  | 			hash.update("FetchCompileWasmMainTemplatePlugin"); | 
					
						
							|  |  |  | 			hash.update("1"); | 
					
						
							|  |  |  | 			hash.update(`${mainTemplate.outputOptions.webassemblyModuleFilename}`); | 
					
						
							| 
									
										
										
										
											2017-10-30 20:56:57 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = FetchCompileWasmMainTemplatePlugin; |