UNPKG

4.52 kBJavaScriptView Raw
1const isAbsolute = new RegExp("^([a-z]+://|//)"),
2 isRelative = new RegExp("^[.]{0,2}/"),
3 hasOwnProperty = Array.prototype.hasOwnProperty;
4
5export const viewLibs = new Map();
6export const isAbsoluteUrl = url => isAbsolute.test(url);
7
8export const viewResolve = (name, options) => {
9 var dist = viewLibs.get(name),
10 main = name,
11 path = null,
12 base = typeof location !== "undefined" ? location : "";
13
14 if (options) {
15 if (typeof options.base === "string") base = options.base;
16 path = removeFrontSlash(options.path);
17 }
18
19 if (dist) {
20 path = path || dist.main;
21 main = removeBackSlash(dist.origin || main);
22 if (dist.version) main = `${name}@${dist.version}`;
23 if (path) main = `${main}/${path}`;
24 } else if (path) {
25 if (isAbsolute.test(main)) main = new URL(main, base).origin;
26 else if (isRelative.test(main)) main = "";
27 main = `${main}/${path}`;
28 }
29
30 if (isAbsolute.test(main)) {
31 return main;
32 } else if (isRelative.test(main)) {
33 return new URL(main, base).href;
34 } else {
35 if (!main.length || /^[\s._]/.test(main) || /\s$/.test(main))
36 throw new Error("illegal name");
37 return "https://unpkg.com/" + main;
38 }
39};
40
41export const viewRequireFrom = (resolver, root) => {
42 const modules = new Map(),
43 queue = [],
44 map = queue.map,
45 some = queue.some,
46 getRoot = () => {
47 return !root && typeof window !== "undefined" ? window : root;
48 },
49 requireRelative = base => {
50 return name => {
51 var url = resolver(name + "", base),
52 module = modules.get(url);
53 if (!module)
54 modules.set(
55 url,
56 (module = new Promise((resolve, reject) => {
57 root = getRoot();
58 const script = root.document.createElement("script");
59 script.onload = function() {
60 try {
61 resolve(queue.pop()(requireRelative(url)));
62 } catch (error) {
63 reject(new Error("invalid module"));
64 }
65 script.remove();
66 };
67 script.onerror = function() {
68 reject(new Error("unable to load module"));
69 script.remove();
70 };
71 script.async = true;
72 script.src = url;
73 root.define = define;
74 root.document.head.appendChild(script);
75 }))
76 );
77 return module;
78 };
79 },
80 requireOne = requireRelative(null);
81
82 function require(name) {
83 return arguments.length > 1
84 ? Promise.all(map.call(arguments, requireOne)).then(merge)
85 : requireOne(name);
86 }
87
88 require.root = getRoot;
89
90 define.amd = {};
91
92 return require;
93
94 function define(name, dependencies, factory) {
95 if (arguments.length < 3) (factory = dependencies), (dependencies = name);
96 if (arguments.length < 2) (factory = dependencies), (dependencies = []);
97 queue.push(
98 some.call(dependencies, isexports)
99 ? function(require) {
100 var exports = {};
101 return Promise.all(
102 map.call(dependencies, function(name) {
103 return isexports((name += "")) ? exports : require(name);
104 })
105 ).then(function(dependencies) {
106 factory.apply(null, dependencies);
107 return exports;
108 });
109 }
110 : function(require) {
111 return Promise.all(map.call(dependencies, require)).then(function(
112 dependencies
113 ) {
114 return typeof factory === "function"
115 ? factory.apply(null, dependencies)
116 : factory;
117 });
118 }
119 );
120 }
121};
122
123export const viewRequire = viewRequireFrom(viewResolve);
124
125// INTERNALS
126
127const isexports = name => name + "" === "exports";
128
129const removeFrontSlash = path => {
130 if (typeof path === "string" && path.substring(0, 1) === "/")
131 path = path.substring(1);
132 return path;
133};
134
135const removeBackSlash = path => {
136 if (typeof path === "string" && path.substring(path.length - 1) === "/")
137 path = path.substring(0, path.substring);
138 return path;
139};
140
141const merge = modules => {
142 var o = {},
143 i = -1,
144 n = modules.length,
145 m,
146 k;
147 while (++i < n) {
148 for (k in (m = modules[i])) {
149 if (hasOwnProperty.call(m, k)) {
150 if (m[k] == null) Object.defineProperty(o, k, { get: getter(m, k) });
151 else o[k] = m[k];
152 }
153 }
154 }
155 return o;
156};
157
158const getter = (object, name) => {
159 return () => object[name];
160};