2016-10-12 12:07:54 +00:00
|
|
|
import 'typings-global'
|
2016-10-06 21:00:29 +00:00
|
|
|
|
2016-10-12 13:41:09 +00:00
|
|
|
import * as path from 'path'
|
2016-10-11 23:41:30 +00:00
|
|
|
import * as q from 'q'
|
|
|
|
import { Objectmap } from 'lik'
|
|
|
|
|
|
|
|
class Smartsystem {
|
2016-10-12 12:01:15 +00:00
|
|
|
lazyModules = new Objectmap<LazyModule<any>>()
|
2016-10-11 23:41:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* add lazyModule to Smartsystem
|
|
|
|
*/
|
2016-10-12 12:01:15 +00:00
|
|
|
addLazyModule(lazyModuleArg: LazyModule<any>) {
|
2016-10-11 23:41:30 +00:00
|
|
|
this.lazyModules.add(lazyModuleArg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the internal smartsystem
|
|
|
|
let smartsystem = new Smartsystem()
|
|
|
|
|
|
|
|
/**
|
|
|
|
* defines a LazyModule
|
|
|
|
*/
|
2016-10-14 01:07:37 +00:00
|
|
|
|
|
|
|
export type TLoader = 'npm' | 'systemjs'
|
|
|
|
|
2016-10-11 23:41:30 +00:00
|
|
|
export class LazyModule<T> {
|
|
|
|
name: string
|
2016-10-12 12:01:15 +00:00
|
|
|
nameIsPath: boolean
|
2016-10-11 23:41:30 +00:00
|
|
|
cwd: string
|
2016-10-12 12:01:15 +00:00
|
|
|
whenLoaded: q.Promise<T>
|
2016-10-14 01:07:37 +00:00
|
|
|
loader: TLoader = 'npm'
|
2016-10-12 12:01:15 +00:00
|
|
|
private whenLoadedDeferred: q.Deferred<T>
|
2016-12-10 18:46:47 +00:00
|
|
|
constructor(nameArg: string, cwdArg: string) {
|
|
|
|
if (!cwdArg) {
|
|
|
|
throw new Error('You must specify a directory to resolve from!')
|
|
|
|
}
|
2016-10-11 23:41:30 +00:00
|
|
|
this.name = nameArg
|
|
|
|
this.cwd = cwdArg
|
2016-10-12 12:01:15 +00:00
|
|
|
smartsystem.addLazyModule(this) // add module to smartsystem instance
|
|
|
|
this.nameIsPath = /\.\//.test(this.name) // figure out if name is path
|
2016-10-12 13:41:09 +00:00
|
|
|
if (this.nameIsPath) {
|
2016-10-14 01:07:37 +00:00
|
|
|
this.name = path.join(this.cwd, this.name)
|
2016-10-12 13:41:09 +00:00
|
|
|
}
|
2016-10-12 12:01:15 +00:00
|
|
|
this.whenLoadedDeferred = q.defer<T>()
|
|
|
|
this.whenLoaded = this.whenLoadedDeferred.promise
|
2016-10-11 23:41:30 +00:00
|
|
|
}
|
|
|
|
|
2016-10-14 01:07:37 +00:00
|
|
|
setLoader(loaderArg: TLoader) {
|
|
|
|
this.loader = loaderArg
|
|
|
|
}
|
|
|
|
|
2016-10-11 23:41:30 +00:00
|
|
|
/**
|
|
|
|
* loads the module
|
|
|
|
*/
|
|
|
|
load(): q.Promise<T> {
|
|
|
|
let done = q.defer<T>()
|
|
|
|
let loadedModule: T
|
2016-10-14 01:07:37 +00:00
|
|
|
if (this.loader === 'npm') {
|
2016-10-14 01:24:29 +00:00
|
|
|
loadedModule = require(this.name)
|
|
|
|
done.resolve(loadedModule)
|
|
|
|
} else if (this.loader === 'systemjs') {
|
|
|
|
let systemjs = require('systemjs')
|
|
|
|
systemjs.import(this.name).then((m) => {
|
|
|
|
loadedModule = m
|
|
|
|
this.whenLoadedDeferred.resolve(loadedModule)
|
|
|
|
done.resolve(loadedModule)
|
|
|
|
}).catch(err => { console.log(err) })
|
2016-10-14 01:07:37 +00:00
|
|
|
} else {
|
2016-10-14 01:24:29 +00:00
|
|
|
throw Error('loader not supported')
|
2016-10-14 01:07:37 +00:00
|
|
|
}
|
2016-10-11 23:41:30 +00:00
|
|
|
return done.promise
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* loads additional lazy modules specified as arguments and returns them in the promise for easy use
|
|
|
|
*/
|
|
|
|
loadAlso(...args: LazyModule<any>[]) {
|
2016-10-14 01:07:37 +00:00
|
|
|
|
2016-10-11 23:41:30 +00:00
|
|
|
}
|
2016-10-14 01:24:29 +00:00
|
|
|
}
|