///
interface IContext {
import(name: string): Promise;
}
type IImportDef = (e: any) => void;
type IExportDef = (name, value) => void;
type ISetup = () => void | Promise;
type IModuleSetup = (exports: IExportDef, context: IContext ) => IModule;
interface IModule {
setters: IImportDef[];
execute: ISetup;
}
const merge = (target, source) => {
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
};
const enumerable = true, configurable = true;
class System {
/**
* Returns absolute url for given module id
* @param id module identifier
* @returns absolute URL
*/
public static resolve(id) {
return AmdLoader.instance.resolveSource(id);
}
public static import(name) {
return AmdLoader.instance.import(name);
}
public static register(
imports: string[],
setup: IModuleSetup);
public static register(
name: string,
imports: string[],
setup: IModuleSetup);
public static register(
nameOrImports: string | string[],
importsOrSetup: string[] | IModuleSetup,
setup?: IModuleSetup) {
const instance = AmdLoader.instance;
const currentModule: Module = document.currentScript?.[currentModuleSymbol] ?? AmdLoader.current;
const name = typeof nameOrImports === "string"
? nameOrImports
: void 0;
let imports = importsOrSetup as string[];
if (arguments.length === 2) {
imports = nameOrImports as string[];
setup = importsOrSetup as IModuleSetup;
}
const module = name ? instance.get(name) : currentModule;
if (module.packed) {
for(const d of imports) {
const absolutePath = module.require.resolve(d);
const dm = instance.get(absolutePath);
if (/\.(css|less)$/i.test(absolutePath)) {
// we will not add it as a dependency
// ass css/less are packed.
dm.packed = true;
}
module.dependencies.push(dm);
}
} else {
for(const d of imports) {
const absolutePath = module.require.resolve(d);
const dm = instance.get(absolutePath);
module.dependencies.push(dm);
}
}
module.isLoaded = true;
if (module.exportVar) {
module.exports = AmdLoader.globalVar[module.exportVar];
}
module.setup = setup;
module.loader = promiseDone;
const r = module.setup((key, value) => {
if (typeof key === "object") {
merge(module.exports, key);
if (!module.exports.default) {
module.exports.default = module.exports;
}
return module.exports;
}
module.exports[key] = value;
return value;
}, module);
module.resolver = () => {
const resolved = (async () => {
const ds = [];
const { setters } = r;
let isCircularDependency;
let index = 0;
for (const iterator of module.dependencies) {
const set = setters[index++];
if (iterator.isResolved) {
set(iterator.getExports());
continue;
}
const setP = this.import(iterator).then(set);
if (iterator.isDependentOn(module)) {
isCircularDependency = true;
continue;
}
ds.push(setP);
}
await Promise.all(ds);
if (isCircularDependency) {
await new Promise((resolve) => setTimeout(resolve,1));
}
const rp = r.execute() as any;
if (rp?.then) {
await rp;
}
module.isResolved = true;
module.getExports();
if (module.postExports) {
module.postExports();
}
if (module.dynamicImports) {
for (const iterator of module.dynamicImports) {
if (iterator.replacedModule.importPromise) {
continue;
}
await this.import(iterator.replacedModule);
}
}
return module.exports;
})();
module.resolver = () => resolved;
return resolved;
};
return module;
}
}