@jsenv/core 27.0.0-alpha.63 → 27.0.0-alpha.64
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/html_supervisor_installer.js +1 -1
- package/dist/html_supervisor_installer.js.map +2 -2
- package/dist/s.js +626 -0
- package/dist/s.js.map +207 -0
- package/main.js +1 -0
- package/package.json +6 -6
- package/src/build/build.js +23 -8
- package/src/build/inject_global_version_mappings.js +18 -5
- package/src/build/start_build_server.js +38 -29
- package/src/dev/start_dev_server.js +1 -1
- package/src/execute/runtimes/browsers/from_playwright.js +10 -0
- package/src/execute/runtimes/node/node_process.js +8 -0
- package/src/omega/kitchen.js +52 -134
- package/src/omega/server/file_service.js +34 -17
- package/src/omega/url_graph/url_graph_load.js +10 -17
- package/src/omega/url_graph/url_info_transformations.js +1 -4
- package/src/omega/url_graph.js +6 -2
- package/src/omega/url_specifier_encoding.js +59 -0
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +1 -1
- package/src/plugins/importmap/jsenv_plugin_importmap.js +2 -4
- package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +51 -42
- package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -4
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +3 -5
- package/src/plugins/inline/jsenv_plugin_inline_query_param.js +1 -4
- package/src/plugins/inline/jsenv_plugin_js_inline_content.js +1 -4
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +4 -0
- package/src/plugins/plugins.js +4 -1
- package/src/plugins/transpilation/as_js_classic/client/s.js +362 -807
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +28 -12
- package/src/plugins/transpilation/as_js_classic/{jsenv_plugin_workers_type_module_as_classic.js → jsenv_plugin_as_js_classic_workers.js} +2 -2
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +165 -133
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +5 -2
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -2
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +4 -1
- package/src/test/execute_plan.js +32 -13
- package/src/test/execute_test_plan.js +2 -0
- package/src/test/logs_file_execution.js +47 -38
- package/src/plugins/transpilation/as_js_classic/client/s.js.md +0 -1
- package/src/plugins/transpilation/fetch_original_url_info.js +0 -30
package/src/omega/kitchen.js
CHANGED
|
@@ -12,6 +12,7 @@ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
|
|
|
12
12
|
import { normalizeUrl, setUrlFilename } from "@jsenv/utils/urls/url_utils.js"
|
|
13
13
|
|
|
14
14
|
import { createPluginController } from "../plugins/plugin_controller.js"
|
|
15
|
+
import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
|
|
15
16
|
import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
|
|
16
17
|
import { RUNTIME_COMPAT } from "./compat/runtime_compat.js"
|
|
17
18
|
import { defaultRuntimeCompat } from "./compat/default_runtime_compat.js"
|
|
@@ -53,7 +54,7 @@ export const createKitchen = ({
|
|
|
53
54
|
scenario,
|
|
54
55
|
})
|
|
55
56
|
const jsenvDirectoryUrl = new URL(".jsenv/", rootDirectoryUrl).href
|
|
56
|
-
const
|
|
57
|
+
const kitchenContext = {
|
|
57
58
|
signal,
|
|
58
59
|
logger,
|
|
59
60
|
rootDirectoryUrl,
|
|
@@ -144,7 +145,7 @@ export const createKitchen = ({
|
|
|
144
145
|
let resolvedUrl = pluginController.callHooksUntil(
|
|
145
146
|
"resolveUrl",
|
|
146
147
|
reference,
|
|
147
|
-
|
|
148
|
+
kitchenContext,
|
|
148
149
|
)
|
|
149
150
|
if (!resolvedUrl) {
|
|
150
151
|
throw new Error(`NO_RESOLVE`)
|
|
@@ -159,7 +160,7 @@ export const createKitchen = ({
|
|
|
159
160
|
pluginController.callHooks(
|
|
160
161
|
"redirectUrl",
|
|
161
162
|
reference,
|
|
162
|
-
|
|
163
|
+
kitchenContext,
|
|
163
164
|
(returnValue) => {
|
|
164
165
|
const normalizedReturnValue = normalizeUrl(returnValue)
|
|
165
166
|
if (normalizedReturnValue === reference.url) {
|
|
@@ -172,7 +173,7 @@ export const createKitchen = ({
|
|
|
172
173
|
)
|
|
173
174
|
|
|
174
175
|
const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url)
|
|
175
|
-
applyReferenceEffectsOnUrlInfo(reference, urlInfo,
|
|
176
|
+
applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext)
|
|
176
177
|
|
|
177
178
|
const referenceUrlObject = new URL(reference.url)
|
|
178
179
|
reference.searchParams = referenceUrlObject.searchParams
|
|
@@ -186,7 +187,7 @@ export const createKitchen = ({
|
|
|
186
187
|
pluginController.callHooks(
|
|
187
188
|
"transformUrlSearchParams",
|
|
188
189
|
reference,
|
|
189
|
-
|
|
190
|
+
kitchenContext,
|
|
190
191
|
(returnValue) => {
|
|
191
192
|
Object.keys(returnValue).forEach((key) => {
|
|
192
193
|
referenceUrlObject.searchParams.set(key, returnValue[key])
|
|
@@ -197,10 +198,10 @@ export const createKitchen = ({
|
|
|
197
198
|
const returnValue = pluginController.callHooksUntil(
|
|
198
199
|
"formatUrl",
|
|
199
200
|
reference,
|
|
200
|
-
|
|
201
|
+
kitchenContext,
|
|
201
202
|
)
|
|
202
203
|
reference.generatedSpecifier = returnValue || reference.generatedUrl
|
|
203
|
-
reference.generatedSpecifier =
|
|
204
|
+
reference.generatedSpecifier = urlSpecifierEncoding.encode(reference)
|
|
204
205
|
return urlInfo
|
|
205
206
|
} catch (error) {
|
|
206
207
|
throw createResolveUrlError({
|
|
@@ -210,7 +211,7 @@ export const createKitchen = ({
|
|
|
210
211
|
})
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
|
-
|
|
214
|
+
kitchenContext.resolveReference = resolveReference
|
|
214
215
|
const urlInfoTransformer = createUrlInfoTransformer({
|
|
215
216
|
logger,
|
|
216
217
|
urlGraph,
|
|
@@ -257,7 +258,7 @@ export const createKitchen = ({
|
|
|
257
258
|
},
|
|
258
259
|
})
|
|
259
260
|
|
|
260
|
-
const fetchUrlContent = async ({ reference,
|
|
261
|
+
const fetchUrlContent = async (urlInfo, { reference, context }) => {
|
|
261
262
|
if (reference.external) {
|
|
262
263
|
urlInfo.external = true
|
|
263
264
|
return
|
|
@@ -342,40 +343,32 @@ export const createKitchen = ({
|
|
|
342
343
|
await urlInfoTransformer.initTransformations(urlInfo, context)
|
|
343
344
|
}
|
|
344
345
|
|
|
345
|
-
const _cook = async ({
|
|
346
|
-
reference,
|
|
347
|
-
urlInfo,
|
|
348
|
-
outDirectoryUrl,
|
|
346
|
+
const _cook = async (urlInfo, dishContext) => {
|
|
349
347
|
// during dev/test clientRuntimeCompat is a single runtime
|
|
350
348
|
// during build clientRuntimeCompat is runtimeCompat
|
|
351
|
-
clientRuntimeCompat = runtimeCompat
|
|
352
|
-
|
|
353
|
-
}) => {
|
|
354
|
-
baseContext.isSupportedOnCurrentClients = (feature) => {
|
|
349
|
+
const { clientRuntimeCompat = runtimeCompat } = dishContext
|
|
350
|
+
kitchenContext.isSupportedOnCurrentClients = (feature) => {
|
|
355
351
|
return RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature)
|
|
356
352
|
}
|
|
357
353
|
const context = {
|
|
358
|
-
...
|
|
359
|
-
|
|
360
|
-
outDirectoryUrl,
|
|
354
|
+
...kitchenContext,
|
|
355
|
+
...dishContext,
|
|
361
356
|
clientRuntimeCompat,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
})
|
|
374
|
-
},
|
|
357
|
+
}
|
|
358
|
+
const { cookDuringCook = cook } = dishContext
|
|
359
|
+
context.cook = (urlInfo, nestedDishContext) => {
|
|
360
|
+
return cookDuringCook(urlInfo, {
|
|
361
|
+
outDirectoryUrl: dishContext.outDirectoryUrl,
|
|
362
|
+
clientRuntimeCompat: dishContext.clientRuntimeCompat,
|
|
363
|
+
...nestedDishContext,
|
|
364
|
+
})
|
|
365
|
+
}
|
|
366
|
+
context.fetchUrlContent = (urlInfo, { reference }) => {
|
|
367
|
+
return fetchUrlContent(urlInfo, { reference, context })
|
|
375
368
|
}
|
|
376
369
|
|
|
377
370
|
// "fetchUrlContent" hook
|
|
378
|
-
await fetchUrlContent({ reference
|
|
371
|
+
await fetchUrlContent(urlInfo, { reference: context.reference, context })
|
|
379
372
|
if (urlInfo.external) {
|
|
380
373
|
return
|
|
381
374
|
}
|
|
@@ -547,7 +540,7 @@ export const createKitchen = ({
|
|
|
547
540
|
} catch (error) {
|
|
548
541
|
throw createTransformUrlContentError({
|
|
549
542
|
pluginController,
|
|
550
|
-
reference,
|
|
543
|
+
reference: context.reference,
|
|
551
544
|
urlInfo,
|
|
552
545
|
error,
|
|
553
546
|
})
|
|
@@ -570,7 +563,7 @@ export const createKitchen = ({
|
|
|
570
563
|
} catch (error) {
|
|
571
564
|
throw createFinalizeUrlContentError({
|
|
572
565
|
pluginController,
|
|
573
|
-
reference,
|
|
566
|
+
reference: context.reference,
|
|
574
567
|
urlInfo,
|
|
575
568
|
error,
|
|
576
569
|
})
|
|
@@ -598,44 +591,30 @@ export const createKitchen = ({
|
|
|
598
591
|
},
|
|
599
592
|
)
|
|
600
593
|
}
|
|
601
|
-
const cook = memoizeCook(async (
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (!writeGeneratedFiles || !outDirectoryUrl) {
|
|
606
|
-
return
|
|
607
|
-
}
|
|
608
|
-
const { generatedUrl } = urlInfo
|
|
609
|
-
// writing result inside ".jsenv" directory (debug purposes)
|
|
610
|
-
if (!generatedUrl || !generatedUrl.startsWith("file:")) {
|
|
611
|
-
return
|
|
612
|
-
}
|
|
613
|
-
// use writeSync to avoid concurrency on writing the file
|
|
614
|
-
const write = gotError ? writeFileSync : writeFileSync
|
|
615
|
-
write(new URL(generatedUrl), urlInfo.content)
|
|
616
|
-
const { sourcemapGeneratedUrl, sourcemap } = urlInfo
|
|
617
|
-
if (sourcemapGeneratedUrl && sourcemap) {
|
|
618
|
-
write(
|
|
619
|
-
new URL(sourcemapGeneratedUrl),
|
|
620
|
-
JSON.stringify(sourcemap, null, " "),
|
|
621
|
-
)
|
|
622
|
-
}
|
|
594
|
+
const cook = memoizeCook(async (urlInfo, context) => {
|
|
595
|
+
if (!writeGeneratedFiles || !context.outDirectoryUrl) {
|
|
596
|
+
await _cook(urlInfo, context)
|
|
597
|
+
return
|
|
623
598
|
}
|
|
624
|
-
|
|
599
|
+
// writing result inside ".jsenv" directory (debug purposes)
|
|
625
600
|
try {
|
|
626
|
-
await _cook(
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
601
|
+
await _cook(urlInfo, context)
|
|
602
|
+
} finally {
|
|
603
|
+
const { generatedUrl } = urlInfo
|
|
604
|
+
if (generatedUrl && generatedUrl.startsWith("file:")) {
|
|
605
|
+
writeFileSync(new URL(generatedUrl), urlInfo.content)
|
|
606
|
+
const { sourcemapGeneratedUrl, sourcemap } = urlInfo
|
|
607
|
+
if (sourcemapGeneratedUrl && sourcemap) {
|
|
608
|
+
writeFileSync(
|
|
609
|
+
new URL(sourcemapGeneratedUrl),
|
|
610
|
+
JSON.stringify(sourcemap, null, " "),
|
|
611
|
+
)
|
|
612
|
+
}
|
|
613
|
+
}
|
|
635
614
|
}
|
|
636
615
|
})
|
|
637
|
-
|
|
638
|
-
|
|
616
|
+
kitchenContext.fetchUrlContent = fetchUrlContent
|
|
617
|
+
kitchenContext.cook = cook
|
|
639
618
|
|
|
640
619
|
const prepareEntryPoint = (params) => {
|
|
641
620
|
const entryReference = createReference(params)
|
|
@@ -654,7 +633,7 @@ export const createKitchen = ({
|
|
|
654
633
|
urlInfoTransformer,
|
|
655
634
|
rootDirectoryUrl,
|
|
656
635
|
jsenvDirectoryUrl,
|
|
657
|
-
|
|
636
|
+
kitchenContext,
|
|
658
637
|
cook,
|
|
659
638
|
prepareEntryPoint,
|
|
660
639
|
injectReference,
|
|
@@ -663,8 +642,7 @@ export const createKitchen = ({
|
|
|
663
642
|
|
|
664
643
|
const memoizeCook = (cook) => {
|
|
665
644
|
const pendingDishes = new Map()
|
|
666
|
-
return async (
|
|
667
|
-
const { urlInfo } = params
|
|
645
|
+
return async (urlInfo, context) => {
|
|
668
646
|
const { url, modifiedTimestamp } = urlInfo
|
|
669
647
|
const pendingDish = pendingDishes.get(url)
|
|
670
648
|
if (pendingDish) {
|
|
@@ -679,7 +657,7 @@ const memoizeCook = (cook) => {
|
|
|
679
657
|
pendingDishes.delete(url)
|
|
680
658
|
}
|
|
681
659
|
const timestamp = Date.now()
|
|
682
|
-
const promise = cook(
|
|
660
|
+
const promise = cook(urlInfo, context)
|
|
683
661
|
pendingDishes.set(url, {
|
|
684
662
|
timestamp,
|
|
685
663
|
promise,
|
|
@@ -833,66 +811,6 @@ const determineFileUrlForOutDirectory = ({ urlInfo, context }) => {
|
|
|
833
811
|
})
|
|
834
812
|
}
|
|
835
813
|
|
|
836
|
-
const urlSpecifierFormat = {
|
|
837
|
-
encode: (reference) => {
|
|
838
|
-
const { generatedSpecifier } = reference
|
|
839
|
-
if (generatedSpecifier.then) {
|
|
840
|
-
return generatedSpecifier.then((value) => {
|
|
841
|
-
reference.generatedSpecifier = value
|
|
842
|
-
return urlSpecifierFormat.encode(reference)
|
|
843
|
-
})
|
|
844
|
-
}
|
|
845
|
-
// allow plugin to return a function to bypas default formatting
|
|
846
|
-
// (which is to use JSON.stringify when url is referenced inside js)
|
|
847
|
-
if (typeof generatedSpecifier === "function") {
|
|
848
|
-
return generatedSpecifier()
|
|
849
|
-
}
|
|
850
|
-
const formatter = formatters[reference.type]
|
|
851
|
-
const value = formatter
|
|
852
|
-
? formatter.encode(generatedSpecifier)
|
|
853
|
-
: generatedSpecifier
|
|
854
|
-
if (reference.escape) {
|
|
855
|
-
return reference.escape(value)
|
|
856
|
-
}
|
|
857
|
-
return value
|
|
858
|
-
},
|
|
859
|
-
decode: (reference) => {
|
|
860
|
-
const formatter = formatters[reference.type]
|
|
861
|
-
return formatter
|
|
862
|
-
? formatter.decode(reference.generatedSpecifier)
|
|
863
|
-
: reference.generatedSpecifier
|
|
864
|
-
},
|
|
865
|
-
}
|
|
866
|
-
const formatters = {
|
|
867
|
-
"js_import_export": { encode: JSON.stringify, decode: JSON.parse },
|
|
868
|
-
"js_url_specifier": { encode: JSON.stringify, decode: JSON.parse },
|
|
869
|
-
"css_@import": { encode: JSON.stringify, code: JSON.stringify },
|
|
870
|
-
// https://github.com/webpack-contrib/css-loader/pull/627/files
|
|
871
|
-
"css_url": {
|
|
872
|
-
encode: (url) => {
|
|
873
|
-
// If url is already wrapped in quotes, remove them
|
|
874
|
-
url = formatters.css_url.decode(url)
|
|
875
|
-
// Should url be wrapped?
|
|
876
|
-
// See https://drafts.csswg.org/css-values-3/#urls
|
|
877
|
-
if (/["'() \t\n]/.test(url)) {
|
|
878
|
-
return `"${url.replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`
|
|
879
|
-
}
|
|
880
|
-
return url
|
|
881
|
-
},
|
|
882
|
-
decode: (url) => {
|
|
883
|
-
const firstChar = url[0]
|
|
884
|
-
const lastChar = url[url.length - 1]
|
|
885
|
-
if (firstChar === `"` && lastChar === `"`) {
|
|
886
|
-
return url.slice(1, -1)
|
|
887
|
-
}
|
|
888
|
-
if (firstChar === `'` && lastChar === `'`) {
|
|
889
|
-
return url.slice(1, -1)
|
|
890
|
-
}
|
|
891
|
-
return url
|
|
892
|
-
},
|
|
893
|
-
},
|
|
894
|
-
}
|
|
895
|
-
|
|
896
814
|
// import { getOriginalPosition } from "@jsenv/core/src/utils/sourcemap/original_position.js"
|
|
897
815
|
// const getUrlSite = async (
|
|
898
816
|
// urlInfo,
|
|
@@ -44,24 +44,32 @@ export const createFileService = ({
|
|
|
44
44
|
if (responseFromPlugin) {
|
|
45
45
|
return responseFromPlugin
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
47
|
+
let reference
|
|
48
|
+
const parentUrl = inferParentFromRequest(request, rootDirectoryUrl)
|
|
49
|
+
if (parentUrl) {
|
|
50
|
+
reference = urlGraph.inferReference(request.ressource, parentUrl)
|
|
51
|
+
}
|
|
52
|
+
if (!reference) {
|
|
53
|
+
const entryPoint = kitchen.prepareEntryPoint({
|
|
54
|
+
trace: parentUrl || rootDirectoryUrl,
|
|
55
|
+
parentUrl: parentUrl || rootDirectoryUrl,
|
|
56
|
+
type: "entry_point",
|
|
57
|
+
specifier: request.ressource,
|
|
58
|
+
})
|
|
59
|
+
reference = entryPoint[0]
|
|
60
|
+
}
|
|
61
|
+
const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url)
|
|
62
|
+
|
|
52
63
|
const ifNoneMatch = request.headers["if-none-match"]
|
|
53
64
|
if (ifNoneMatch && urlInfo.contentEtag === ifNoneMatch) {
|
|
54
65
|
return {
|
|
55
66
|
status: 304,
|
|
56
67
|
headers: {
|
|
57
68
|
"cache-control": `private,max-age=0,must-revalidate`,
|
|
69
|
+
...urlInfo.responseHeaders,
|
|
58
70
|
},
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
|
-
const referenceFromGraph = urlGraph.inferReference(
|
|
62
|
-
reference.url,
|
|
63
|
-
reference.parentUrl,
|
|
64
|
-
)
|
|
65
73
|
try {
|
|
66
74
|
// urlInfo objects are reused, they must be "reset" before cooking them again
|
|
67
75
|
if (
|
|
@@ -76,20 +84,21 @@ export const createFileService = ({
|
|
|
76
84
|
urlInfo.type = null
|
|
77
85
|
urlInfo.subtype = null
|
|
78
86
|
urlInfo.timing = {}
|
|
87
|
+
urlInfo.responseHeaders = {}
|
|
79
88
|
}
|
|
80
89
|
const { runtimeName, runtimeVersion } = parseUserAgentHeader(
|
|
81
90
|
request.headers["user-agent"],
|
|
82
91
|
)
|
|
83
|
-
await kitchen.cook({
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
await kitchen.cook(urlInfo, {
|
|
93
|
+
request,
|
|
94
|
+
reference,
|
|
95
|
+
clientRuntimeCompat: {
|
|
96
|
+
[runtimeName]: runtimeVersion,
|
|
97
|
+
},
|
|
86
98
|
outDirectoryUrl:
|
|
87
99
|
scenario === "dev"
|
|
88
100
|
? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/`
|
|
89
101
|
: `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`,
|
|
90
|
-
clientRuntimeCompat: {
|
|
91
|
-
[runtimeName]: runtimeVersion,
|
|
92
|
-
},
|
|
93
102
|
})
|
|
94
103
|
let { response, contentType, content, contentEtag } = urlInfo
|
|
95
104
|
if (response) {
|
|
@@ -103,6 +112,7 @@ export const createFileService = ({
|
|
|
103
112
|
"content-length": Buffer.byteLength(content),
|
|
104
113
|
"cache-control": `private,max-age=0,must-revalidate`,
|
|
105
114
|
"eTag": contentEtag,
|
|
115
|
+
...urlInfo.responseHeaders,
|
|
106
116
|
},
|
|
107
117
|
body: content,
|
|
108
118
|
timing: urlInfo.timing,
|
|
@@ -167,7 +177,6 @@ export const createFileService = ({
|
|
|
167
177
|
}
|
|
168
178
|
return async (request) => {
|
|
169
179
|
let response = await getResponse(request)
|
|
170
|
-
|
|
171
180
|
return response
|
|
172
181
|
}
|
|
173
182
|
}
|
|
@@ -175,7 +184,15 @@ export const createFileService = ({
|
|
|
175
184
|
const inferParentFromRequest = (request, rootDirectoryUrl) => {
|
|
176
185
|
const { referer } = request.headers
|
|
177
186
|
if (!referer) {
|
|
178
|
-
return
|
|
187
|
+
return null
|
|
188
|
+
}
|
|
189
|
+
const refererUrlObject = new URL(referer)
|
|
190
|
+
refererUrlObject.searchParams.delete("hmr")
|
|
191
|
+
refererUrlObject.searchParams.delete("v")
|
|
192
|
+
const { pathname, search } = refererUrlObject
|
|
193
|
+
if (pathname.startsWith("/@fs/")) {
|
|
194
|
+
const fsRootRelativeUrl = pathname.slice("/@fs/".length)
|
|
195
|
+
return `file:///${fsRootRelativeUrl}${search}`
|
|
179
196
|
}
|
|
180
197
|
return moveUrl({
|
|
181
198
|
url: referer,
|
|
@@ -5,32 +5,31 @@ export const loadUrlGraph = async ({
|
|
|
5
5
|
urlGraph,
|
|
6
6
|
kitchen,
|
|
7
7
|
startLoading,
|
|
8
|
+
writeGeneratedFiles,
|
|
8
9
|
outDirectoryUrl,
|
|
9
10
|
clientRuntimeCompat,
|
|
10
11
|
}) => {
|
|
11
|
-
if (outDirectoryUrl) {
|
|
12
|
+
if (writeGeneratedFiles && outDirectoryUrl) {
|
|
12
13
|
await ensureEmptyDirectory(outDirectoryUrl)
|
|
13
14
|
}
|
|
14
15
|
const promises = []
|
|
15
16
|
const promiseMap = new Map()
|
|
16
|
-
const cook = (
|
|
17
|
+
const cook = (urlInfo, context) => {
|
|
17
18
|
const promiseFromData = promiseMap.get(urlInfo)
|
|
18
19
|
if (promiseFromData) return promiseFromData
|
|
19
|
-
const promise = _cook({
|
|
20
|
-
urlInfo,
|
|
20
|
+
const promise = _cook(urlInfo, {
|
|
21
21
|
outDirectoryUrl,
|
|
22
22
|
clientRuntimeCompat,
|
|
23
|
-
...
|
|
23
|
+
...context,
|
|
24
24
|
})
|
|
25
25
|
promises.push(promise)
|
|
26
26
|
promiseMap.set(urlInfo, promise)
|
|
27
27
|
return promise
|
|
28
28
|
}
|
|
29
|
-
const _cook = async (
|
|
30
|
-
await kitchen.cook({
|
|
31
|
-
urlInfo,
|
|
29
|
+
const _cook = async (urlInfo, context) => {
|
|
30
|
+
await kitchen.cook(urlInfo, {
|
|
32
31
|
cookDuringCook: cook,
|
|
33
|
-
...
|
|
32
|
+
...context,
|
|
34
33
|
})
|
|
35
34
|
const { references } = urlInfo
|
|
36
35
|
references.forEach((reference) => {
|
|
@@ -46,10 +45,7 @@ export const loadUrlGraph = async ({
|
|
|
46
45
|
const referencedUrlInfo = urlGraph.reuseOrCreateUrlInfo(
|
|
47
46
|
reference.generatedUrl,
|
|
48
47
|
)
|
|
49
|
-
cook({
|
|
50
|
-
reference,
|
|
51
|
-
urlInfo: referencedUrlInfo,
|
|
52
|
-
})
|
|
48
|
+
cook(referencedUrlInfo, { reference })
|
|
53
49
|
})
|
|
54
50
|
}
|
|
55
51
|
startLoading(
|
|
@@ -61,10 +57,7 @@ export const loadUrlGraph = async ({
|
|
|
61
57
|
specifier,
|
|
62
58
|
})
|
|
63
59
|
entryUrlInfo.data.isEntryPoint = true
|
|
64
|
-
cook({
|
|
65
|
-
reference: entryReference,
|
|
66
|
-
urlInfo: entryUrlInfo,
|
|
67
|
-
})
|
|
60
|
+
cook(entryUrlInfo, { reference: entryReference })
|
|
68
61
|
return [entryReference, entryUrlInfo]
|
|
69
62
|
},
|
|
70
63
|
)
|
|
@@ -91,10 +91,7 @@ export const createUrlInfoTransformer = ({
|
|
|
91
91
|
specifierColumn: column,
|
|
92
92
|
})
|
|
93
93
|
try {
|
|
94
|
-
await context.cook({
|
|
95
|
-
reference: sourcemapReference,
|
|
96
|
-
urlInfo: sourcemapUrlInfo,
|
|
97
|
-
})
|
|
94
|
+
await context.cook(sourcemapUrlInfo, { reference: sourcemapReference })
|
|
98
95
|
const sourcemap = JSON.parse(sourcemapUrlInfo.content)
|
|
99
96
|
urlInfo.sourcemap = normalizeSourcemap(urlInfo, sourcemap)
|
|
100
97
|
} catch (e) {
|
package/src/omega/url_graph.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { urlToRelativeUrl } from "@jsenv/filesystem"
|
|
2
|
+
import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
|
|
2
3
|
|
|
3
4
|
export const createUrlGraph = ({
|
|
4
5
|
clientFileChangeCallbackList,
|
|
@@ -23,13 +24,15 @@ export const createUrlGraph = ({
|
|
|
23
24
|
urlInfos[url] = urlInfo
|
|
24
25
|
return urlInfo
|
|
25
26
|
}
|
|
26
|
-
const inferReference = (
|
|
27
|
+
const inferReference = (specifier, parentUrl) => {
|
|
27
28
|
const parentUrlInfo = urlInfos[parentUrl]
|
|
28
29
|
if (!parentUrlInfo) {
|
|
29
30
|
return null
|
|
30
31
|
}
|
|
31
32
|
const firstReferenceOnThatUrl = parentUrlInfo.references.find(
|
|
32
|
-
(reference) =>
|
|
33
|
+
(reference) => {
|
|
34
|
+
return urlSpecifierEncoding.decode(reference) === specifier
|
|
35
|
+
},
|
|
33
36
|
)
|
|
34
37
|
return firstReferenceOnThatUrl
|
|
35
38
|
}
|
|
@@ -192,5 +195,6 @@ const createUrlInfo = (url) => {
|
|
|
192
195
|
sourcemap: null,
|
|
193
196
|
sourcemapReference: null,
|
|
194
197
|
timing: {},
|
|
198
|
+
responseHeaders: {},
|
|
195
199
|
}
|
|
196
200
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export const urlSpecifierEncoding = {
|
|
2
|
+
encode: (reference) => {
|
|
3
|
+
const { generatedSpecifier } = reference
|
|
4
|
+
if (generatedSpecifier.then) {
|
|
5
|
+
return generatedSpecifier.then((value) => {
|
|
6
|
+
reference.generatedSpecifier = value
|
|
7
|
+
return urlSpecifierEncoding.encode(reference)
|
|
8
|
+
})
|
|
9
|
+
}
|
|
10
|
+
// allow plugin to return a function to bypas default formatting
|
|
11
|
+
// (which is to use JSON.stringify when url is referenced inside js)
|
|
12
|
+
if (typeof generatedSpecifier === "function") {
|
|
13
|
+
return generatedSpecifier()
|
|
14
|
+
}
|
|
15
|
+
const formatter = formatters[reference.type]
|
|
16
|
+
const value = formatter
|
|
17
|
+
? formatter.encode(generatedSpecifier)
|
|
18
|
+
: generatedSpecifier
|
|
19
|
+
if (reference.escape) {
|
|
20
|
+
return reference.escape(value)
|
|
21
|
+
}
|
|
22
|
+
return value
|
|
23
|
+
},
|
|
24
|
+
decode: (reference) => {
|
|
25
|
+
const formatter = formatters[reference.type]
|
|
26
|
+
return formatter
|
|
27
|
+
? formatter.decode(reference.generatedSpecifier)
|
|
28
|
+
: reference.generatedSpecifier
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
const formatters = {
|
|
32
|
+
"js_import_export": { encode: JSON.stringify, decode: JSON.parse },
|
|
33
|
+
"js_url_specifier": { encode: JSON.stringify, decode: JSON.parse },
|
|
34
|
+
"css_@import": { encode: JSON.stringify, code: JSON.stringify },
|
|
35
|
+
// https://github.com/webpack-contrib/css-loader/pull/627/files
|
|
36
|
+
"css_url": {
|
|
37
|
+
encode: (url) => {
|
|
38
|
+
// If url is already wrapped in quotes, remove them
|
|
39
|
+
url = formatters.css_url.decode(url)
|
|
40
|
+
// Should url be wrapped?
|
|
41
|
+
// See https://drafts.csswg.org/css-values-3/#urls
|
|
42
|
+
if (/["'() \t\n]/.test(url)) {
|
|
43
|
+
return `"${url.replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`
|
|
44
|
+
}
|
|
45
|
+
return url
|
|
46
|
+
},
|
|
47
|
+
decode: (url) => {
|
|
48
|
+
const firstChar = url[0]
|
|
49
|
+
const lastChar = url[url.length - 1]
|
|
50
|
+
if (firstChar === `"` && lastChar === `"`) {
|
|
51
|
+
return url.slice(1, -1)
|
|
52
|
+
}
|
|
53
|
+
if (firstChar === `'` && lastChar === `'`) {
|
|
54
|
+
return url.slice(1, -1)
|
|
55
|
+
}
|
|
56
|
+
return url
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
}
|
|
@@ -185,7 +185,7 @@ export const installHtmlSupervisor = ({ logs, measurePerf }) => {
|
|
|
185
185
|
dequeue()
|
|
186
186
|
}
|
|
187
187
|
if (
|
|
188
|
-
document.readyState !== "
|
|
188
|
+
document.readyState !== "interactive" &&
|
|
189
189
|
document.readyState !== "complete"
|
|
190
190
|
) {
|
|
191
191
|
document.addEventListener("readystatechange", () => {
|
|
@@ -130,9 +130,8 @@ export const jsenvPluginImportmap = () => {
|
|
|
130
130
|
contentType: "application/importmap+json",
|
|
131
131
|
content: textNode.value,
|
|
132
132
|
})
|
|
133
|
-
await context.cook({
|
|
133
|
+
await context.cook(inlineImportmapUrlInfo, {
|
|
134
134
|
reference: inlineImportmapReference,
|
|
135
|
-
urlInfo: inlineImportmapUrlInfo,
|
|
136
135
|
})
|
|
137
136
|
setHtmlNodeGeneratedText(importmap, {
|
|
138
137
|
generatedText: inlineImportmapUrlInfo.content,
|
|
@@ -154,9 +153,8 @@ export const jsenvPluginImportmap = () => {
|
|
|
154
153
|
const importmapUrlInfo = context.urlGraph.getUrlInfo(
|
|
155
154
|
importmapReference.url,
|
|
156
155
|
)
|
|
157
|
-
await context.cook({
|
|
156
|
+
await context.cook(importmapUrlInfo, {
|
|
158
157
|
reference: importmapReference,
|
|
159
|
-
urlInfo: importmapUrlInfo,
|
|
160
158
|
})
|
|
161
159
|
onHtmlImportmapParsed(
|
|
162
160
|
JSON.parse(importmapUrlInfo.content),
|