| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | const System = { | 
					
						
							|  |  |  | 	register: (name, deps, fn) => { | 
					
						
							|  |  |  | 		if (!System.registry) { | 
					
						
							|  |  |  | 			throw new Error("System is no initialized"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (typeof name !== "string") { | 
					
						
							|  |  |  | 			fn = deps; | 
					
						
							|  |  |  | 			deps = name; | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 			name = System._nextName; | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (!Array.isArray(deps)) { | 
					
						
							|  |  |  | 			fn = deps; | 
					
						
							|  |  |  | 			deps = []; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		const dynamicExport = result => { | 
					
						
							|  |  |  | 			if (System.registry[name] !== entry) { | 
					
						
							|  |  |  | 				throw new Error(`Module ${name} calls dynamicExport too late`); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			entry.exports = result; | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 			for (const mod of Object.keys(System.registry)) { | 
					
						
							|  |  |  | 				const m = System.registry[mod]; | 
					
						
							|  |  |  | 				if (!m.deps) continue; | 
					
						
							|  |  |  | 				for (let i = 0; i < m.deps.length; i++) { | 
					
						
							|  |  |  | 					const dep = m.deps[i]; | 
					
						
							|  |  |  | 					if (dep !== name) continue; | 
					
						
							|  |  |  | 					const setters = m.mod.setters[i]; | 
					
						
							|  |  |  | 					setters(result); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-05-13 04:29:50 +08:00
										 |  |  | 		const systemContext = { | 
					
						
							|  |  |  | 			meta: { | 
					
						
							|  |  |  | 				url: `/${name}.js` | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			import() { | 
					
						
							|  |  |  | 				return Promise.resolve(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		if (name in System.registry) { | 
					
						
							|  |  |  | 			throw new Error(`Module ${name} is already registered`); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 		const mod = fn(dynamicExport, systemContext); | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		if (deps.length > 0) { | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 			if (!Array.isArray(mod.setters)) { | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 				throw new Error( | 
					
						
							|  |  |  | 					`Module ${name} must have setters, because it has dependencies` | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 			if (mod.setters.length !== deps.length) { | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 				throw new Error( | 
					
						
							|  |  |  | 					`Module ${name} has incorrect number of setters for the dependencies` | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 		const entry = { | 
					
						
							|  |  |  | 			name, | 
					
						
							|  |  |  | 			deps, | 
					
						
							|  |  |  | 			fn, | 
					
						
							|  |  |  | 			mod, | 
					
						
							|  |  |  | 			executed: false, | 
					
						
							|  |  |  | 			exports: undefined | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		System.registry[name] = entry; | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 	set: (name, exports) => { | 
					
						
							|  |  |  | 		System.registry[name] = { | 
					
						
							|  |  |  | 			name, | 
					
						
							|  |  |  | 			executed: true, | 
					
						
							|  |  |  | 			exports | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 	registry: undefined, | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 	_require: undefined, | 
					
						
							|  |  |  | 	_nextName: "(anonym)", | 
					
						
							|  |  |  | 	setRequire: req => { | 
					
						
							|  |  |  | 		System._require = req; | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 	init: modules => { | 
					
						
							|  |  |  | 		System.registry = {}; | 
					
						
							|  |  |  | 		if (modules) { | 
					
						
							|  |  |  | 			for (const name of Object.keys(modules)) { | 
					
						
							|  |  |  | 				System.registry[name] = { | 
					
						
							|  |  |  | 					executed: true, | 
					
						
							|  |  |  | 					exports: modules[name] | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	execute: name => { | 
					
						
							|  |  |  | 		const m = System.registry[name]; | 
					
						
							|  |  |  | 		if (!m) throw new Error(`Module ${name} not registered`); | 
					
						
							|  |  |  | 		if (m.executed) throw new Error(`Module ${name} was already executed`); | 
					
						
							|  |  |  | 		return System.ensureExecuted(name); | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	ensureExecuted: name => { | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 		let m = System.registry[name]; | 
					
						
							|  |  |  | 		if (!m && System._require) { | 
					
						
							|  |  |  | 			const oldName = System._nextName; | 
					
						
							|  |  |  | 			System._nextName = name; | 
					
						
							|  |  |  | 			System._require(name); | 
					
						
							|  |  |  | 			System._nextName = oldName; | 
					
						
							|  |  |  | 			m = System.registry[name]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!m) { | 
					
						
							|  |  |  | 			throw new Error(`Module ${name} not registered`); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 		if (!m.executed) { | 
					
						
							|  |  |  | 			m.executed = true; | 
					
						
							|  |  |  | 			for (let i = 0; i < m.deps.length; i++) { | 
					
						
							|  |  |  | 				const dep = m.deps[i]; | 
					
						
							| 
									
										
										
										
											2020-03-05 20:31:58 +08:00
										 |  |  | 				const setters = m.mod.setters[i]; | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 				System.ensureExecuted(dep); | 
					
						
							| 
									
										
										
										
											2020-04-14 21:13:15 +08:00
										 |  |  | 				const { exports } = System.registry[dep]; | 
					
						
							|  |  |  | 				if (exports !== undefined) setters(exports); | 
					
						
							| 
									
										
										
										
											2019-04-10 19:48:47 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			m.mod.execute(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return m.exports; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | module.exports = System; |