@jsenv/core 41.5.5 → 41.5.7
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.
package/dist/build/build.js
CHANGED
|
@@ -6,7 +6,7 @@ import { jsenvPluginTranspilation, jsenvPluginJsModuleFallback } from "@jsenv/pl
|
|
|
6
6
|
import { memoryUsage } from "node:process";
|
|
7
7
|
import { readFileSync, existsSync, realpathSync, readdirSync, lstatSync, statSync } from "node:fs";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
9
|
-
import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
9
|
+
import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP, applyContentEditsOnSourcemap, composeSourcemaps } from "@jsenv/sourcemap";
|
|
10
10
|
import { createPluginsController } from "@jsenv/server/src/plugins_controller.js";
|
|
11
11
|
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
12
12
|
import { WebSocketResponse, pickContentType } from "@jsenv/server";
|
|
@@ -2823,6 +2823,84 @@ const createUrlInfoTransformer = ({
|
|
|
2823
2823
|
return sourcemap;
|
|
2824
2824
|
};
|
|
2825
2825
|
|
|
2826
|
+
// Sourcemap composition is deferred: each transformation pushes an element
|
|
2827
|
+
// here and "urlInfo.sourcemap" becomes a lazy view resolving the whole
|
|
2828
|
+
// pending chain on first read (with caching, invalidated by a new push or
|
|
2829
|
+
// an assignment). Any reader at any point sees a map matching the current
|
|
2830
|
+
// content — the guarantee is the same as composing at each transformation.
|
|
2831
|
+
//
|
|
2832
|
+
// An element is either a normalized sourcemap, or a magic source edit
|
|
2833
|
+
// record ({ contentEdits, getSourcemap }). Edits applied on top of an
|
|
2834
|
+
// existing map become position shifts on that map — orders of magnitude
|
|
2835
|
+
// cheaper than composing with a generated full-file map, and lossless:
|
|
2836
|
+
// the map keeps its own density instead of being redensified by the edit
|
|
2837
|
+
// map's word boundaries. When the shift cannot apply (no map below, or an
|
|
2838
|
+
// unsupported edit shape), getSourcemap() materializes the generated map
|
|
2839
|
+
// and composition proceeds as usual.
|
|
2840
|
+
const pendingSourcemapsMap = new WeakMap();
|
|
2841
|
+
const resolveSourcemapChain = (urlInfo, base, pendings) => {
|
|
2842
|
+
let current = base;
|
|
2843
|
+
let batch = current ? [current] : [];
|
|
2844
|
+
const composeBatch = () => {
|
|
2845
|
+
if (batch.length > 1) {
|
|
2846
|
+
const composed = composeSourcemaps(batch);
|
|
2847
|
+
current = composed ? normalizeSourcemap(urlInfo, composed) : null;
|
|
2848
|
+
} else {
|
|
2849
|
+
current = batch.length ? batch[0] : null;
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
for (const pending of pendings) {
|
|
2853
|
+
if (!pending.contentEdits) {
|
|
2854
|
+
batch.push(pending);
|
|
2855
|
+
continue;
|
|
2856
|
+
}
|
|
2857
|
+
composeBatch();
|
|
2858
|
+
if (current) {
|
|
2859
|
+
const shifted = applyContentEditsOnSourcemap(
|
|
2860
|
+
current,
|
|
2861
|
+
pending.contentEdits,
|
|
2862
|
+
);
|
|
2863
|
+
if (shifted) {
|
|
2864
|
+
current = shifted;
|
|
2865
|
+
batch = [current];
|
|
2866
|
+
continue;
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
const materialized = pending.getSourcemap();
|
|
2870
|
+
batch = current ? [current] : [];
|
|
2871
|
+
if (materialized) {
|
|
2872
|
+
batch.push(normalizeSourcemap(urlInfo, materialized));
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
composeBatch();
|
|
2876
|
+
return current;
|
|
2877
|
+
};
|
|
2878
|
+
const addSourcemapElement = (urlInfo, element) => {
|
|
2879
|
+
const existingPendings = pendingSourcemapsMap.get(urlInfo);
|
|
2880
|
+
if (existingPendings) {
|
|
2881
|
+
existingPendings.push(element);
|
|
2882
|
+
return;
|
|
2883
|
+
}
|
|
2884
|
+
const pendings = [element];
|
|
2885
|
+
pendingSourcemapsMap.set(urlInfo, pendings);
|
|
2886
|
+
let base = urlInfo.sourcemap;
|
|
2887
|
+
Object.defineProperty(urlInfo, "sourcemap", {
|
|
2888
|
+
configurable: true,
|
|
2889
|
+
enumerable: true,
|
|
2890
|
+
get: () => {
|
|
2891
|
+
if (pendings.length > 0) {
|
|
2892
|
+
base = resolveSourcemapChain(urlInfo, base, pendings);
|
|
2893
|
+
pendings.length = 0;
|
|
2894
|
+
}
|
|
2895
|
+
return base;
|
|
2896
|
+
},
|
|
2897
|
+
set: (value) => {
|
|
2898
|
+
pendings.length = 0;
|
|
2899
|
+
base = value;
|
|
2900
|
+
},
|
|
2901
|
+
});
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2826
2904
|
const resetContent = (urlInfo) => {
|
|
2827
2905
|
urlInfo.contentFinalized = false;
|
|
2828
2906
|
urlInfo.originalContent = undefined;
|
|
@@ -2969,33 +3047,35 @@ const createUrlInfoTransformer = ({
|
|
|
2969
3047
|
}
|
|
2970
3048
|
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
2971
3049
|
// hand it back as a getter that generates the map on first read, so that
|
|
2972
|
-
// nothing is generated for a kitchen that throws sourcemaps away
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
3050
|
+
// nothing is generated for a kitchen that throws sourcemaps away.
|
|
3051
|
+
// "sourcemapEdits" (magic source results) goes further: the edits are
|
|
3052
|
+
// pushed and the generated map is materialized only if the shift fast
|
|
3053
|
+
// path cannot apply.
|
|
3054
|
+
if (mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)) {
|
|
3055
|
+
const { sourcemapEdits } = transformations;
|
|
3056
|
+
if (sourcemapEdits) {
|
|
3057
|
+
addSourcemapElement(urlInfo, {
|
|
3058
|
+
contentEdits: sourcemapEdits,
|
|
3059
|
+
getSourcemap: () => transformations.sourcemap,
|
|
3060
|
+
});
|
|
3061
|
+
urlInfo.sourcemapIsWrong = urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
3062
|
+
} else {
|
|
3063
|
+
const sourcemap = transformations.sourcemap;
|
|
3064
|
+
if (sourcemap) {
|
|
3065
|
+
addSourcemapElement(urlInfo, normalizeSourcemap(urlInfo, sourcemap));
|
|
3066
|
+
// A plugin is allowed to modify url content
|
|
3067
|
+
// without returning a sourcemap
|
|
3068
|
+
// This is the case for preact and react plugins.
|
|
3069
|
+
// They are currently generating wrong source mappings
|
|
3070
|
+
// when used.
|
|
3071
|
+
// Generating the correct sourcemap in this situation
|
|
3072
|
+
// is a nightmare no-one could solve in years so
|
|
3073
|
+
// jsenv won't emit a warning and use the following strategy:
|
|
3074
|
+
// "no sourcemap is better than wrong sourcemap"
|
|
3075
|
+
urlInfo.sourcemapIsWrong =
|
|
3076
|
+
urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
2999
3079
|
}
|
|
3000
3080
|
if (contentModified && urlInfo.contentFinalized) {
|
|
3001
3081
|
applyContentEffects(urlInfo);
|
|
@@ -6,7 +6,7 @@ import { createPluginsController } from "@jsenv/server/src/plugins_controller.js
|
|
|
6
6
|
import { parseHtml, injectJsenvScript, stringifyHtmlAst, parseCssUrls, getHtmlNodeAttribute, getHtmlNodePosition, getHtmlNodeAttributePosition, setHtmlNodeAttributes, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, getHtmlNodeText, analyzeScriptNode, visitHtmlNodes, parseJsUrls, getUrlForContentInsideJs, renderCssTemplateLiteral, applyBabelPlugins, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn } from "@jsenv/ast";
|
|
7
7
|
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
8
8
|
import { jsenvPluginTranspilation } from "@jsenv/plugin-transpilation";
|
|
9
|
-
import { createMagicSource, composeTwoSourcemaps, generateSourcemapFileUrl, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
9
|
+
import { createMagicSource, composeTwoSourcemaps, generateSourcemapFileUrl, generateSourcemapDataUrl, SOURCEMAP, applyContentEditsOnSourcemap, composeSourcemaps } from "@jsenv/sourcemap";
|
|
10
10
|
import { bundleJsModules } from "@jsenv/plugin-bundling";
|
|
11
11
|
import { randomUUID } from "node:crypto";
|
|
12
12
|
import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/plugins/filesystem/filesystem_error_to_response.js";
|
|
@@ -10151,6 +10151,84 @@ const createUrlInfoTransformer = ({
|
|
|
10151
10151
|
return sourcemap;
|
|
10152
10152
|
};
|
|
10153
10153
|
|
|
10154
|
+
// Sourcemap composition is deferred: each transformation pushes an element
|
|
10155
|
+
// here and "urlInfo.sourcemap" becomes a lazy view resolving the whole
|
|
10156
|
+
// pending chain on first read (with caching, invalidated by a new push or
|
|
10157
|
+
// an assignment). Any reader at any point sees a map matching the current
|
|
10158
|
+
// content — the guarantee is the same as composing at each transformation.
|
|
10159
|
+
//
|
|
10160
|
+
// An element is either a normalized sourcemap, or a magic source edit
|
|
10161
|
+
// record ({ contentEdits, getSourcemap }). Edits applied on top of an
|
|
10162
|
+
// existing map become position shifts on that map — orders of magnitude
|
|
10163
|
+
// cheaper than composing with a generated full-file map, and lossless:
|
|
10164
|
+
// the map keeps its own density instead of being redensified by the edit
|
|
10165
|
+
// map's word boundaries. When the shift cannot apply (no map below, or an
|
|
10166
|
+
// unsupported edit shape), getSourcemap() materializes the generated map
|
|
10167
|
+
// and composition proceeds as usual.
|
|
10168
|
+
const pendingSourcemapsMap = new WeakMap();
|
|
10169
|
+
const resolveSourcemapChain = (urlInfo, base, pendings) => {
|
|
10170
|
+
let current = base;
|
|
10171
|
+
let batch = current ? [current] : [];
|
|
10172
|
+
const composeBatch = () => {
|
|
10173
|
+
if (batch.length > 1) {
|
|
10174
|
+
const composed = composeSourcemaps(batch);
|
|
10175
|
+
current = composed ? normalizeSourcemap(urlInfo, composed) : null;
|
|
10176
|
+
} else {
|
|
10177
|
+
current = batch.length ? batch[0] : null;
|
|
10178
|
+
}
|
|
10179
|
+
};
|
|
10180
|
+
for (const pending of pendings) {
|
|
10181
|
+
if (!pending.contentEdits) {
|
|
10182
|
+
batch.push(pending);
|
|
10183
|
+
continue;
|
|
10184
|
+
}
|
|
10185
|
+
composeBatch();
|
|
10186
|
+
if (current) {
|
|
10187
|
+
const shifted = applyContentEditsOnSourcemap(
|
|
10188
|
+
current,
|
|
10189
|
+
pending.contentEdits,
|
|
10190
|
+
);
|
|
10191
|
+
if (shifted) {
|
|
10192
|
+
current = shifted;
|
|
10193
|
+
batch = [current];
|
|
10194
|
+
continue;
|
|
10195
|
+
}
|
|
10196
|
+
}
|
|
10197
|
+
const materialized = pending.getSourcemap();
|
|
10198
|
+
batch = current ? [current] : [];
|
|
10199
|
+
if (materialized) {
|
|
10200
|
+
batch.push(normalizeSourcemap(urlInfo, materialized));
|
|
10201
|
+
}
|
|
10202
|
+
}
|
|
10203
|
+
composeBatch();
|
|
10204
|
+
return current;
|
|
10205
|
+
};
|
|
10206
|
+
const addSourcemapElement = (urlInfo, element) => {
|
|
10207
|
+
const existingPendings = pendingSourcemapsMap.get(urlInfo);
|
|
10208
|
+
if (existingPendings) {
|
|
10209
|
+
existingPendings.push(element);
|
|
10210
|
+
return;
|
|
10211
|
+
}
|
|
10212
|
+
const pendings = [element];
|
|
10213
|
+
pendingSourcemapsMap.set(urlInfo, pendings);
|
|
10214
|
+
let base = urlInfo.sourcemap;
|
|
10215
|
+
Object.defineProperty(urlInfo, "sourcemap", {
|
|
10216
|
+
configurable: true,
|
|
10217
|
+
enumerable: true,
|
|
10218
|
+
get: () => {
|
|
10219
|
+
if (pendings.length > 0) {
|
|
10220
|
+
base = resolveSourcemapChain(urlInfo, base, pendings);
|
|
10221
|
+
pendings.length = 0;
|
|
10222
|
+
}
|
|
10223
|
+
return base;
|
|
10224
|
+
},
|
|
10225
|
+
set: (value) => {
|
|
10226
|
+
pendings.length = 0;
|
|
10227
|
+
base = value;
|
|
10228
|
+
},
|
|
10229
|
+
});
|
|
10230
|
+
};
|
|
10231
|
+
|
|
10154
10232
|
const resetContent = (urlInfo) => {
|
|
10155
10233
|
urlInfo.contentFinalized = false;
|
|
10156
10234
|
urlInfo.originalContent = undefined;
|
|
@@ -10297,33 +10375,35 @@ const createUrlInfoTransformer = ({
|
|
|
10297
10375
|
}
|
|
10298
10376
|
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
10299
10377
|
// hand it back as a getter that generates the map on first read, so that
|
|
10300
|
-
// nothing is generated for a kitchen that throws sourcemaps away
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10378
|
+
// nothing is generated for a kitchen that throws sourcemaps away.
|
|
10379
|
+
// "sourcemapEdits" (magic source results) goes further: the edits are
|
|
10380
|
+
// pushed and the generated map is materialized only if the shift fast
|
|
10381
|
+
// path cannot apply.
|
|
10382
|
+
if (mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)) {
|
|
10383
|
+
const { sourcemapEdits } = transformations;
|
|
10384
|
+
if (sourcemapEdits) {
|
|
10385
|
+
addSourcemapElement(urlInfo, {
|
|
10386
|
+
contentEdits: sourcemapEdits,
|
|
10387
|
+
getSourcemap: () => transformations.sourcemap,
|
|
10388
|
+
});
|
|
10389
|
+
urlInfo.sourcemapIsWrong = urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
10390
|
+
} else {
|
|
10391
|
+
const sourcemap = transformations.sourcemap;
|
|
10392
|
+
if (sourcemap) {
|
|
10393
|
+
addSourcemapElement(urlInfo, normalizeSourcemap(urlInfo, sourcemap));
|
|
10394
|
+
// A plugin is allowed to modify url content
|
|
10395
|
+
// without returning a sourcemap
|
|
10396
|
+
// This is the case for preact and react plugins.
|
|
10397
|
+
// They are currently generating wrong source mappings
|
|
10398
|
+
// when used.
|
|
10399
|
+
// Generating the correct sourcemap in this situation
|
|
10400
|
+
// is a nightmare no-one could solve in years so
|
|
10401
|
+
// jsenv won't emit a warning and use the following strategy:
|
|
10402
|
+
// "no sourcemap is better than wrong sourcemap"
|
|
10403
|
+
urlInfo.sourcemapIsWrong =
|
|
10404
|
+
urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
10405
|
+
}
|
|
10406
|
+
}
|
|
10327
10407
|
}
|
|
10328
10408
|
if (contentModified && urlInfo.contentFinalized) {
|
|
10329
10409
|
applyContentEffects(urlInfo);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "41.5.
|
|
3
|
+
"version": "41.5.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tool to develop, test and build js projects",
|
|
6
6
|
"repository": {
|
|
@@ -74,13 +74,13 @@
|
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@jsenv/ast": "6.10.1",
|
|
77
|
-
"@jsenv/js-module-fallback": "1.6.
|
|
78
|
-
"@jsenv/plugin-bundling": "2.10.
|
|
79
|
-
"@jsenv/plugin-minification": "1.7.
|
|
80
|
-
"@jsenv/plugin-supervisor": "1.8.
|
|
81
|
-
"@jsenv/plugin-transpilation": "1.7.
|
|
77
|
+
"@jsenv/js-module-fallback": "1.6.4",
|
|
78
|
+
"@jsenv/plugin-bundling": "2.10.22",
|
|
79
|
+
"@jsenv/plugin-minification": "1.7.17",
|
|
80
|
+
"@jsenv/plugin-supervisor": "1.8.19",
|
|
81
|
+
"@jsenv/plugin-transpilation": "1.7.4",
|
|
82
82
|
"@jsenv/server": "17.6.3",
|
|
83
|
-
"@jsenv/sourcemap": "1.4.
|
|
83
|
+
"@jsenv/sourcemap": "1.4.5",
|
|
84
84
|
"react-table": "7.8.0"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { writeFileSync } from "@jsenv/filesystem";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
applyContentEditsOnSourcemap,
|
|
4
|
+
composeSourcemaps,
|
|
4
5
|
generateSourcemapDataUrl,
|
|
5
6
|
SOURCEMAP,
|
|
6
7
|
} from "@jsenv/sourcemap";
|
|
@@ -81,6 +82,84 @@ export const createUrlInfoTransformer = ({
|
|
|
81
82
|
return sourcemap;
|
|
82
83
|
};
|
|
83
84
|
|
|
85
|
+
// Sourcemap composition is deferred: each transformation pushes an element
|
|
86
|
+
// here and "urlInfo.sourcemap" becomes a lazy view resolving the whole
|
|
87
|
+
// pending chain on first read (with caching, invalidated by a new push or
|
|
88
|
+
// an assignment). Any reader at any point sees a map matching the current
|
|
89
|
+
// content — the guarantee is the same as composing at each transformation.
|
|
90
|
+
//
|
|
91
|
+
// An element is either a normalized sourcemap, or a magic source edit
|
|
92
|
+
// record ({ contentEdits, getSourcemap }). Edits applied on top of an
|
|
93
|
+
// existing map become position shifts on that map — orders of magnitude
|
|
94
|
+
// cheaper than composing with a generated full-file map, and lossless:
|
|
95
|
+
// the map keeps its own density instead of being redensified by the edit
|
|
96
|
+
// map's word boundaries. When the shift cannot apply (no map below, or an
|
|
97
|
+
// unsupported edit shape), getSourcemap() materializes the generated map
|
|
98
|
+
// and composition proceeds as usual.
|
|
99
|
+
const pendingSourcemapsMap = new WeakMap();
|
|
100
|
+
const resolveSourcemapChain = (urlInfo, base, pendings) => {
|
|
101
|
+
let current = base;
|
|
102
|
+
let batch = current ? [current] : [];
|
|
103
|
+
const composeBatch = () => {
|
|
104
|
+
if (batch.length > 1) {
|
|
105
|
+
const composed = composeSourcemaps(batch);
|
|
106
|
+
current = composed ? normalizeSourcemap(urlInfo, composed) : null;
|
|
107
|
+
} else {
|
|
108
|
+
current = batch.length ? batch[0] : null;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
for (const pending of pendings) {
|
|
112
|
+
if (!pending.contentEdits) {
|
|
113
|
+
batch.push(pending);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
composeBatch();
|
|
117
|
+
if (current) {
|
|
118
|
+
const shifted = applyContentEditsOnSourcemap(
|
|
119
|
+
current,
|
|
120
|
+
pending.contentEdits,
|
|
121
|
+
);
|
|
122
|
+
if (shifted) {
|
|
123
|
+
current = shifted;
|
|
124
|
+
batch = [current];
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const materialized = pending.getSourcemap();
|
|
129
|
+
batch = current ? [current] : [];
|
|
130
|
+
if (materialized) {
|
|
131
|
+
batch.push(normalizeSourcemap(urlInfo, materialized));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
composeBatch();
|
|
135
|
+
return current;
|
|
136
|
+
};
|
|
137
|
+
const addSourcemapElement = (urlInfo, element) => {
|
|
138
|
+
const existingPendings = pendingSourcemapsMap.get(urlInfo);
|
|
139
|
+
if (existingPendings) {
|
|
140
|
+
existingPendings.push(element);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const pendings = [element];
|
|
144
|
+
pendingSourcemapsMap.set(urlInfo, pendings);
|
|
145
|
+
let base = urlInfo.sourcemap;
|
|
146
|
+
Object.defineProperty(urlInfo, "sourcemap", {
|
|
147
|
+
configurable: true,
|
|
148
|
+
enumerable: true,
|
|
149
|
+
get: () => {
|
|
150
|
+
if (pendings.length > 0) {
|
|
151
|
+
base = resolveSourcemapChain(urlInfo, base, pendings);
|
|
152
|
+
pendings.length = 0;
|
|
153
|
+
}
|
|
154
|
+
return base;
|
|
155
|
+
},
|
|
156
|
+
set: (value) => {
|
|
157
|
+
pendings.length = 0;
|
|
158
|
+
base = value;
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
84
163
|
const resetContent = (urlInfo) => {
|
|
85
164
|
urlInfo.contentFinalized = false;
|
|
86
165
|
urlInfo.originalContent = undefined;
|
|
@@ -227,33 +306,35 @@ export const createUrlInfoTransformer = ({
|
|
|
227
306
|
}
|
|
228
307
|
// "sourcemap" is read last, and only when it will be used: a plugin can
|
|
229
308
|
// hand it back as a getter that generates the map on first read, so that
|
|
230
|
-
// nothing is generated for a kitchen that throws sourcemaps away
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
309
|
+
// nothing is generated for a kitchen that throws sourcemaps away.
|
|
310
|
+
// "sourcemapEdits" (magic source results) goes further: the edits are
|
|
311
|
+
// pushed and the generated map is materialized only if the shift fast
|
|
312
|
+
// path cannot apply.
|
|
313
|
+
if (mayHaveSourcemap(urlInfo) && shouldHandleSourcemap(urlInfo)) {
|
|
314
|
+
const { sourcemapEdits } = transformations;
|
|
315
|
+
if (sourcemapEdits) {
|
|
316
|
+
addSourcemapElement(urlInfo, {
|
|
317
|
+
contentEdits: sourcemapEdits,
|
|
318
|
+
getSourcemap: () => transformations.sourcemap,
|
|
319
|
+
});
|
|
320
|
+
urlInfo.sourcemapIsWrong = urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
321
|
+
} else {
|
|
322
|
+
const sourcemap = transformations.sourcemap;
|
|
323
|
+
if (sourcemap) {
|
|
324
|
+
addSourcemapElement(urlInfo, normalizeSourcemap(urlInfo, sourcemap));
|
|
325
|
+
// A plugin is allowed to modify url content
|
|
326
|
+
// without returning a sourcemap
|
|
327
|
+
// This is the case for preact and react plugins.
|
|
328
|
+
// They are currently generating wrong source mappings
|
|
329
|
+
// when used.
|
|
330
|
+
// Generating the correct sourcemap in this situation
|
|
331
|
+
// is a nightmare no-one could solve in years so
|
|
332
|
+
// jsenv won't emit a warning and use the following strategy:
|
|
333
|
+
// "no sourcemap is better than wrong sourcemap"
|
|
334
|
+
urlInfo.sourcemapIsWrong =
|
|
335
|
+
urlInfo.sourcemapIsWrong || sourcemapIsWrong;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
257
338
|
}
|
|
258
339
|
if (contentModified && urlInfo.contentFinalized) {
|
|
259
340
|
applyContentEffects(urlInfo);
|