@jsenv/core 36.1.1 → 36.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,449 +0,0 @@
1
- /*
2
- * This file is a modified version of https://github.com/systemjs/systemjs/blob/main/dist/s.js
3
- * with the following changes:
4
- *
5
- * - Code can use aync/await, const, etc because this file is compiled (see dist/s.js)
6
- * - Can use document.currentScript because we don't support IE
7
- * - auto import inline System.register
8
- * - auto import first System.register in web workers
9
- * - queing events in web workers
10
- * - no support for importmap because jsenv don't need it
11
- */
12
-
13
- (function () {
14
- /* eslint-env browser */
15
-
16
- const loadRegistry = Object.create(null);
17
- const registerRegistry = Object.create(null);
18
- let inlineScriptCount = 0;
19
- const System = {};
20
-
21
- const hasDocument = typeof document === "object";
22
- const envGlobal = self;
23
- const isWorker =
24
- !hasDocument &&
25
- typeof envGlobal.WorkerGlobalScope === "function" &&
26
- envGlobal instanceof envGlobal.WorkerGlobalScope;
27
- const isServiceWorker = isWorker && typeof self.skipWaiting === "function";
28
- envGlobal.System = System;
29
-
30
- let baseUrl = envGlobal.location.href.split("#")[0].split("?")[0];
31
- const lastSlashIndex = baseUrl.lastIndexOf("/");
32
- if (lastSlashIndex !== -1) {
33
- baseUrl = baseUrl.slice(0, lastSlashIndex + 1);
34
- }
35
-
36
- const resolveUrl = (specifier, baseUrl) => new URL(specifier, baseUrl).href;
37
-
38
- if (hasDocument) {
39
- const baseElement = document.querySelector("base[href]");
40
- if (baseElement) {
41
- baseUrl = baseElement.href;
42
- }
43
- System.register = (deps, declare) => {
44
- if (!document.currentScript) {
45
- throw new Error(
46
- "unexpected call to System.register (document.currentScript is undefined)",
47
- );
48
- }
49
- if (document.currentScript.__s__) {
50
- registerRegistry[document.currentScript.src] = [deps, declare];
51
- return null;
52
- }
53
- const url =
54
- document.currentScript.src ||
55
- `${window.location.href}__inline_script__${++inlineScriptCount}`;
56
- registerRegistry[url] = [deps, declare];
57
- return _import(url);
58
- };
59
- System.instantiate = (url) => {
60
- const script = createScript(url);
61
- return new Promise(function (resolve, reject) {
62
- let lastWindowErrorUrl;
63
- let lastWindowError;
64
- const windowErrorCallback = (event) => {
65
- lastWindowErrorUrl = event.filename;
66
- lastWindowError = event.error;
67
- };
68
- window.addEventListener("error", windowErrorCallback);
69
- script.addEventListener("error", () => {
70
- window.removeEventListener("error", windowErrorCallback);
71
- reject(`An error occured while loading url with <script> for ${url}`);
72
- });
73
- script.addEventListener("load", () => {
74
- window.removeEventListener("error", windowErrorCallback);
75
- document.head.removeChild(script);
76
- // Note that if an error occurs that isn't caught by this if statement,
77
- // that getRegister will return null and a "did not instantiate" error will be thrown.
78
- if (lastWindowErrorUrl === url) {
79
- reject(lastWindowError);
80
- } else {
81
- resolve();
82
- }
83
- });
84
- document.head.appendChild(script);
85
- });
86
- };
87
- const createScript = (url) => {
88
- const script = document.createElement("script");
89
- script.async = true;
90
- // Only add cross origin for actual cross origin
91
- // this is because Safari triggers for all
92
- // - https://bugs.webkit.org/show_bug.cgi?id=171566
93
- if (url.indexOf(`${self.location.origin}/`)) {
94
- script.crossOrigin = "anonymous";
95
- }
96
- script.__s__ = true;
97
- script.src = url;
98
- return script;
99
- };
100
- }
101
- if (isWorker) {
102
- /*
103
- * SystemJs loads X files before executing the worker/service worker main file
104
- * It mean events dispatched during this phase could be missed
105
- * A warning like the one below is displayed in chrome devtools:
106
- * "Event handler of 'install' event must be added on the initial evaluation of worker script"
107
- * To fix that code below listen for these events early and redispatch them later
108
- * once the worker file is executed (the listeners are installed)
109
- */
110
- const firstImportCallbacks = [];
111
- if (isServiceWorker) {
112
- // for service worker there is more events to listen
113
- // and, to get rid of the warning, we override self.addEventListener
114
- const eventsToCatch = ["message", "install", "activate", "fetch"];
115
- const eventCallbackProxies = {};
116
- const firstImportPromise = new Promise((resolve) => {
117
- firstImportCallbacks.push(resolve);
118
- });
119
- eventsToCatch.forEach((eventName) => {
120
- const eventsToDispatch = [];
121
- const eventCallback = (event) => {
122
- const eventCallbackProxy = eventCallbackProxies[event.type];
123
- if (eventCallbackProxy) {
124
- eventCallbackProxy(event);
125
- } else {
126
- eventsToDispatch.push(event);
127
- event.waitUntil(firstImportPromise);
128
- }
129
- };
130
- self.addEventListener(eventName, eventCallback);
131
- firstImportCallbacks.push(() => {
132
- if (eventsToDispatch.length) {
133
- const eventCallbackProxy =
134
- eventCallbackProxies[eventsToDispatch[0].type];
135
- if (eventCallbackProxy) {
136
- eventsToDispatch.forEach((event) => {
137
- eventCallbackProxy(event);
138
- });
139
- }
140
- eventsToDispatch.length = 0;
141
- }
142
- });
143
- });
144
-
145
- const addEventListener = self.addEventListener;
146
- self.addEventListener = function (eventName, callback, options) {
147
- if (eventsToCatch.indexOf(eventName) > -1) {
148
- eventCallbackProxies[eventName] = callback;
149
- return null;
150
- }
151
- return addEventListener.call(self, eventName, callback, options);
152
- };
153
- } else {
154
- const eventsToCatch = ["message"];
155
- eventsToCatch.forEach((eventName) => {
156
- var eventQueue = [];
157
- var eventCallback = (event) => {
158
- eventQueue.push(event);
159
- };
160
- self.addEventListener(eventName, eventCallback);
161
- firstImportCallbacks.push(() => {
162
- self.removeEventListener(eventName, eventCallback);
163
- eventQueue.forEach(function (event) {
164
- self.dispatchEvent(event);
165
- });
166
- eventQueue.length = 0;
167
- });
168
- });
169
- }
170
-
171
- System.register = async (deps, declare) => {
172
- System.register = () => {
173
- throw new Error(
174
- "unexpected call to System.register (called outside url instantiation)",
175
- );
176
- };
177
- const url = self.location.href;
178
- registerRegistry[url] = [deps, declare];
179
- const namespace = await _import(url);
180
- firstImportCallbacks.forEach((firstImportCallback) => {
181
- firstImportCallback();
182
- });
183
- firstImportCallbacks.length = 0;
184
- return namespace;
185
- };
186
- System.instantiate = async (url) => {
187
- const response = await self.fetch(url, {
188
- credentials: "same-origin",
189
- });
190
- if (!response.ok) {
191
- throw Error(`Failed to fetch module at ${url}`);
192
- }
193
- let source = await response.text();
194
- if (source.indexOf("//# sourceURL=") < 0) {
195
- source += `\n//# sourceURL=${url}`;
196
- }
197
- const register = System.register;
198
- System.register = (deps, declare) => {
199
- registerRegistry[url] = [deps, declare];
200
- };
201
- (0, self.eval)(source);
202
- System.register = register;
203
- };
204
- }
205
-
206
- const _import = (specifier, parentUrl) => {
207
- const url = resolveUrl(specifier, parentUrl);
208
- const load = getOrCreateLoad(url, parentUrl);
209
- if (load.completionPromise) {
210
- if (load.completionPromise === load.namespace) {
211
- return Promise.resolve(load.namespace);
212
- }
213
- return load.completionPromise;
214
- }
215
- return startExecution(load, parentUrl);
216
- };
217
-
218
- const getOrCreateLoad = (url, firstParentUrl) => {
219
- const existingLoad = loadRegistry[url];
220
- if (existingLoad) {
221
- return existingLoad;
222
- }
223
- const namespace = createNamespace();
224
- const load = {
225
- url,
226
- deps: [],
227
- dependencyLoads: [],
228
- instantiatePromise: null,
229
- linkPromise: null,
230
- executePromise: null,
231
- completionPromise: null,
232
- importerSetters: [],
233
- setters: [],
234
- execute: null,
235
- error: null,
236
- hoistedExports: false,
237
- namespace,
238
- };
239
- loadRegistry[url] = load;
240
- load.instantiatePromise = (async () => {
241
- try {
242
- let registration = registerRegistry[url];
243
- if (!registration) {
244
- const instantiateReturnValue = System.instantiate(
245
- url,
246
- firstParentUrl,
247
- );
248
- if (instantiateReturnValue) {
249
- await instantiateReturnValue;
250
- }
251
- registration = registerRegistry[url];
252
- }
253
- if (!registration) {
254
- throw new Error(
255
- `System.register() not called after executing ${url}`,
256
- );
257
- }
258
-
259
- const _export = (firstArg, secondArg) => {
260
- load.hoistedExports = true;
261
- let changed = false;
262
- if (typeof firstArg === "string") {
263
- const name = firstArg;
264
- const value = secondArg;
265
- if (!(name in namespace) || namespace[name] !== value) {
266
- namespace[name] = value;
267
- changed = true;
268
- }
269
- } else {
270
- Object.keys(firstArg).forEach((name) => {
271
- const value = firstArg[name];
272
- if (!(name in namespace) || namespace[name] !== value) {
273
- namespace[name] = value;
274
- changed = true;
275
- }
276
- });
277
- if (firstArg && firstArg.__esModule) {
278
- namespace.__esModule = firstArg.__esModule;
279
- }
280
- }
281
- if (changed) {
282
- load.importerSetters.forEach((importerSetter) => {
283
- if (importerSetter) {
284
- importerSetter(namespace);
285
- }
286
- });
287
- }
288
- return secondArg;
289
- };
290
- const [deps, declare] = registration;
291
- const { setters, execute = () => {} } = declare(_export, {
292
- import: (importId) => _import(importId, url),
293
- meta: createMeta(url),
294
- });
295
- load.deps = deps;
296
- load.setters = setters;
297
- load.execute = execute;
298
- } catch (e) {
299
- load.error = e;
300
- load.execute = null;
301
- }
302
- })();
303
- load.linkPromise = (async () => {
304
- await load.instantiatePromise;
305
- const dependencyLoads = await Promise.all(
306
- load.deps.map(async (dep, index) => {
307
- const setter = load.setters[index];
308
- const dependencyUrl = resolveUrl(dep, url);
309
- const dependencyLoad = getOrCreateLoad(dependencyUrl, url);
310
- if (dependencyLoad.instantiatePromise) {
311
- await dependencyLoad.instantiatePromise;
312
- }
313
- if (setter) {
314
- dependencyLoad.importerSetters.push(setter);
315
- if (
316
- dependencyLoad.hoistedExports ||
317
- !dependencyLoad.instantiatePromise
318
- ) {
319
- setter(dependencyLoad.namespace);
320
- }
321
- }
322
- return dependencyLoad;
323
- }),
324
- );
325
- load.dependencyLoads = dependencyLoads;
326
- })();
327
- return load;
328
- };
329
-
330
- const startExecution = async (load, importerUrl) => {
331
- load.completionPromise = (async () => {
332
- await instantiateAll(load, load, {});
333
- await postOrderExec(load, importerUrl ? [importerUrl] : []);
334
- return load.namespace;
335
- })();
336
- return load.completionPromise;
337
- };
338
-
339
- const instantiateAll = async (load, parent, loaded) => {
340
- if (loaded[load.url]) {
341
- return;
342
- }
343
- loaded[load.url] = true;
344
- try {
345
- if (load.linkPromise) {
346
- // load.linkPromise is null once instantiated
347
- await load.linkPromise;
348
- }
349
- await Promise.all(
350
- load.dependencyLoads.map((dependencyLoad) => {
351
- return instantiateAll(dependencyLoad, parent, loaded);
352
- }),
353
- );
354
- } catch (error) {
355
- if (load.error) {
356
- throw error;
357
- }
358
- load.execute = null;
359
- throw error;
360
- }
361
- };
362
-
363
- const postOrderExec = (load, importStack) => {
364
- if (importStack.indexOf(load.url) > -1) {
365
- return undefined;
366
- }
367
- if (!load.execute) {
368
- if (load.error) {
369
- throw load.error;
370
- }
371
- if (load.executePromise) {
372
- return load.executePromise;
373
- }
374
- return undefined;
375
- }
376
-
377
- // deps execute first, unless circular
378
- const execute = load.execute;
379
- load.execute = null;
380
- const depLoadPromises = [];
381
- load.dependencyLoads.forEach((dependencyLoad) => {
382
- try {
383
- const depImportStack = importStack.slice();
384
- depImportStack.push(load.url);
385
- const depLoadPromise = postOrderExec(dependencyLoad, depImportStack);
386
- if (depLoadPromise) {
387
- depLoadPromises.push(depLoadPromise);
388
- }
389
- } catch (err) {
390
- load.error = err;
391
- throw err;
392
- }
393
- });
394
-
395
- return (async () => {
396
- if (depLoadPromises.length) {
397
- const allDepPromise = Promise.all(depLoadPromises);
398
- await allDepPromise;
399
- }
400
-
401
- try {
402
- const executeReturnValue = execute.call(nullContext);
403
- if (executeReturnValue) {
404
- load.executePromise = executeReturnValue.then(
405
- () => {
406
- load.executePromise = null;
407
- load.completionPromise = load.namespace;
408
- },
409
- (error) => {
410
- load.executePromise = null;
411
- load.error = error;
412
- throw error;
413
- },
414
- );
415
- return;
416
- }
417
- load.instantiatePromise = null;
418
- load.linkPromise = null;
419
- load.completionPromise = load.namespace;
420
- } catch (error) {
421
- load.error = error;
422
- throw error;
423
- } finally {
424
- load.execute = null;
425
- }
426
- })();
427
- };
428
-
429
- // the closest we can get to call(undefined)
430
- const nullContext = Object.freeze(Object.create(null));
431
-
432
- const createMeta = (url) => {
433
- return {
434
- url,
435
- resolve: (id) => resolveUrl(id, url),
436
- };
437
- };
438
-
439
- const createNamespace =
440
- typeof Symbol !== "undefined" && Symbol.toStringTag
441
- ? () => {
442
- const namespace = Object.create(null);
443
- Object.defineProperty(namespace, Symbol.toStringTag, {
444
- value: "Module",
445
- });
446
- return namespace;
447
- }
448
- : () => Object.create(null);
449
- })();
@@ -1,175 +0,0 @@
1
- import { urlToRelativeUrl } from "@jsenv/urls";
2
- import { readFileSync } from "@jsenv/filesystem";
3
- import {
4
- createMagicSource,
5
- composeTwoSourcemaps,
6
- SOURCEMAP,
7
- } from "@jsenv/sourcemap";
8
- import { applyBabelPlugins } from "@jsenv/ast";
9
-
10
- import { requireFromJsenv } from "@jsenv/core/src/helpers/require_from_jsenv.js";
11
- import { requireBabelPlugin } from "../babel/require_babel_plugin.js";
12
- import { babelPluginTransformImportMetaUrl } from "./helpers/babel_plugin_transform_import_meta_url.js";
13
- import { babelPluginTransformImportMetaResolve } from "./helpers/babel_plugin_transform_import_meta_resolve.js";
14
-
15
- // because of https://github.com/rpetrich/babel-plugin-transform-async-to-promises/issues/84
16
- import customAsyncToPromises from "./async-to-promises.js";
17
-
18
- export const systemJsClientFileUrlDefault = new URL(
19
- "./client/s.js",
20
- import.meta.url,
21
- ).href;
22
-
23
- export const convertJsModuleToJsClassic = async ({
24
- systemJsInjection,
25
- systemJsClientFileUrl = systemJsClientFileUrlDefault,
26
- urlInfo,
27
- jsModuleUrlInfo,
28
- }) => {
29
- let jsClassicFormat;
30
- if (urlInfo.isEntryPoint && !jsModuleUrlInfo.data.usesImport) {
31
- // if it's an entry point without dependency (it does not use import)
32
- // then we can use UMD
33
- jsClassicFormat = "umd";
34
- } else {
35
- // otherwise we have to use system in case it's imported
36
- // by an other file (for entry points)
37
- // or to be able to import when it uses import
38
- jsClassicFormat = "system";
39
- }
40
-
41
- urlInfo.data.jsClassicFormat = jsClassicFormat;
42
- const { code, map } = await applyBabelPlugins({
43
- babelPlugins: [
44
- ...(jsClassicFormat === "system"
45
- ? [
46
- // proposal-dynamic-import required with systemjs for babel8:
47
- // https://github.com/babel/babel/issues/10746
48
- requireFromJsenv("@babel/plugin-proposal-dynamic-import"),
49
- requireFromJsenv("@babel/plugin-transform-modules-systemjs"),
50
- [babelPluginRelativeImports, { rootUrl: jsModuleUrlInfo.url }],
51
- [
52
- customAsyncToPromises,
53
- {
54
- asyncAwait: false, // already handled + we might not needs it at all
55
- topLevelAwait: "return",
56
- },
57
- ],
58
- ]
59
- : [
60
- [
61
- requireBabelPlugin("babel-plugin-transform-async-to-promises"),
62
- {
63
- asyncAwait: false, // already handled + we might not needs it at all
64
- topLevelAwait: "simple",
65
- },
66
- ],
67
- babelPluginTransformImportMetaUrl,
68
- babelPluginTransformImportMetaResolve,
69
- requireFromJsenv("@babel/plugin-transform-modules-umd"),
70
- [babelPluginRelativeImports, { rootUrl: jsModuleUrlInfo.url }],
71
- ]),
72
- ],
73
- urlInfo: jsModuleUrlInfo,
74
- });
75
- let sourcemap = jsModuleUrlInfo.sourcemap;
76
- sourcemap = await composeTwoSourcemaps(sourcemap, map);
77
- if (
78
- systemJsInjection &&
79
- jsClassicFormat === "system" &&
80
- urlInfo.isEntryPoint
81
- ) {
82
- const magicSource = createMagicSource(code);
83
- let systemJsFileContent = readFileSync(systemJsClientFileUrl, {
84
- as: "string",
85
- });
86
- const sourcemapFound = SOURCEMAP.readComment({
87
- contentType: "text/javascript",
88
- content: systemJsFileContent,
89
- });
90
- if (sourcemapFound) {
91
- // for now let's remove s.js sourcemap
92
- // because it would likely mess the sourcemap of the entry point itself
93
- systemJsFileContent = SOURCEMAP.writeComment({
94
- contentType: "text/javascript",
95
- content: systemJsFileContent,
96
- specifier: "",
97
- });
98
- }
99
- magicSource.prepend(`${systemJsFileContent}\n\n`);
100
- const magicResult = magicSource.toContentAndSourcemap();
101
- sourcemap = await composeTwoSourcemaps(sourcemap, magicResult.sourcemap);
102
- return {
103
- content: magicResult.content,
104
- sourcemap,
105
- };
106
- }
107
- return {
108
- content: code,
109
- sourcemap,
110
- };
111
- };
112
-
113
- /*
114
- * When systemjs or umd format is used by babel, it will generated UID based on
115
- * the import specifier:
116
- * https://github.com/babel/babel/blob/97d1967826077f15e766778c0d64711399e9a72a/packages/babel-plugin-transform-modules-systemjs/src/index.ts#L498
117
- * But at this stage import specifier are absolute file urls
118
- * This can be mitigated by minification that will rename them.
119
- * But to fix this issue once and for all there is babelPluginRelativeImports below
120
- */
121
- const babelPluginRelativeImports = (babel) => {
122
- const t = babel.types;
123
-
124
- const replaceSpecifierAtPath = (path, state) => {
125
- const specifier = path.node.value;
126
- if (specifier.startsWith("file://")) {
127
- const specifierRelative = urlToRelativeUrl(specifier, state.opts.rootUrl);
128
- path.replaceWith(t.stringLiteral(specifierRelative));
129
- }
130
- };
131
-
132
- return {
133
- name: "relative-imports",
134
- visitor: {
135
- CallExpression: (path, state) => {
136
- if (path.node.callee.type !== "Import") {
137
- // Some other function call, not import();
138
- return;
139
- }
140
- if (path.node.arguments[0].type !== "StringLiteral") {
141
- // Non-string argument, probably a variable or expression, e.g.
142
- // import(moduleId)
143
- // import('./' + moduleName)
144
- return;
145
- }
146
- const sourcePath = path.get("arguments")[0];
147
- if (sourcePath.node.type === "StringLiteral") {
148
- replaceSpecifierAtPath(sourcePath, state);
149
- }
150
- },
151
- ImportDeclaration: (path, state) => {
152
- const sourcePath = path.get("source");
153
- replaceSpecifierAtPath(sourcePath, state);
154
- },
155
- ExportAllDeclaration: (path, state) => {
156
- const sourcePath = path.get("source");
157
- replaceSpecifierAtPath(sourcePath, state);
158
- },
159
- ExportNamedDeclaration: (path, state) => {
160
- if (!path.node.source) {
161
- // This export has no "source", so it's probably
162
- // a local variable or function, e.g.
163
- // export { varName }
164
- // export const constName = ...
165
- // export function funcName() {}
166
- return;
167
- }
168
- const sourcePath = path.get("source");
169
- if (sourcePath.node.type === "StringLiteral") {
170
- replaceSpecifierAtPath(sourcePath, state);
171
- }
172
- },
173
- },
174
- };
175
- };
@@ -1,26 +0,0 @@
1
- export const babelPluginTransformImportMetaResolve = () => {
2
- return {
3
- name: "transform-import-meta-resolve",
4
- visitor: {
5
- Program: (programPath) => {
6
- programPath.traverse({
7
- MemberExpression: (path) => {
8
- const node = path.node;
9
- if (
10
- node.object.type === "MetaProperty" &&
11
- node.object.property.name === "meta" &&
12
- node.property.name === "resolve"
13
- ) {
14
- const firstArg = node.arguments[0];
15
- if (firstArg && firstArg.type === "StringLiteral") {
16
- path.replaceWithSourceString(
17
- `new URL(${firstArg.value}, document.currentScript.src).href`,
18
- );
19
- }
20
- }
21
- },
22
- });
23
- },
24
- },
25
- };
26
- };
@@ -1,47 +0,0 @@
1
- import babelParser from "@babel/parser";
2
-
3
- export const babelPluginTransformImportMetaUrl = (babel) => {
4
- return {
5
- name: "transform-import-meta-url",
6
- visitor: {
7
- Program: (programPath) => {
8
- const currentUrlIdentifier =
9
- programPath.scope.generateUidIdentifier("currentUrl");
10
- let used = false;
11
-
12
- programPath.traverse({
13
- MemberExpression: (path) => {
14
- const node = path.node;
15
- if (
16
- node.object.type === "MetaProperty" &&
17
- node.object.property.name === "meta" &&
18
- node.property.name === "url"
19
- ) {
20
- // const node = babel.types.valueToNode(10)
21
- const identifier = babel.types.identifier(
22
- currentUrlIdentifier.name,
23
- );
24
- const expressionStatement =
25
- babel.types.expressionStatement(identifier);
26
- path.replaceWith(expressionStatement);
27
- used = true;
28
- }
29
- },
30
- });
31
- if (used) {
32
- const ast = generateExpressionAst(`document.currentScript.src`);
33
- programPath.scope.push({
34
- id: currentUrlIdentifier,
35
- init: ast,
36
- });
37
- }
38
- },
39
- },
40
- };
41
- };
42
-
43
- const generateExpressionAst = (expression, options) => {
44
- const { parseExpression } = babelParser;
45
- const ast = parseExpression(expression, options);
46
- return ast;
47
- };