@jsenv/core 27.0.0-alpha.6 → 27.0.0-alpha.62

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.
Files changed (150) hide show
  1. package/dist/event_source_client.js +549 -0
  2. package/dist/event_source_client.js.map +188 -0
  3. package/dist/html_supervisor_installer.js +1236 -0
  4. package/dist/html_supervisor_installer.js.map +337 -0
  5. package/dist/html_supervisor_setup.js +95 -0
  6. package/dist/html_supervisor_setup.js.map +57 -0
  7. package/dist/import_meta_hot.js +86 -0
  8. package/dist/import_meta_hot.js.map +42 -0
  9. package/main.js +8 -1
  10. package/package.json +36 -29
  11. package/readme.md +6 -14
  12. package/src/build/build.js +961 -559
  13. package/src/build/build_urls_generator.js +48 -23
  14. package/src/build/graph_utils.js +31 -0
  15. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  16. package/src/build/inject_service_worker_urls.js +79 -0
  17. package/src/build/resync_ressource_hints.js +68 -0
  18. package/src/build/start_build_server.js +200 -0
  19. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  20. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  21. package/src/dev/start_dev_server.js +150 -34
  22. package/src/execute/execute.js +33 -6
  23. package/src/execute/run.js +19 -56
  24. package/src/execute/runtimes/browsers/from_playwright.js +207 -147
  25. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  26. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  27. package/src/execute/runtimes/node/node_process.js +280 -39
  28. package/src/jsenv_root_directory_url.js +1 -0
  29. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  30. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  31. package/src/omega/compat/runtime_compat.js +50 -0
  32. package/src/omega/errors.js +51 -58
  33. package/src/omega/fetched_content_compliance.js +24 -0
  34. package/src/omega/file_url_converter.js +8 -50
  35. package/src/omega/kitchen.js +475 -308
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +57 -26
  38. package/src/omega/server/user_agent.js +4 -2
  39. package/src/omega/url_graph/url_graph_load.js +22 -7
  40. package/src/omega/url_graph/url_graph_report.js +94 -51
  41. package/src/omega/url_graph/url_info_transformations.js +26 -9
  42. package/src/omega/url_graph.js +80 -16
  43. package/src/omega/web_workers.js +42 -0
  44. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  45. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +19 -12
  46. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  47. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  48. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +46 -0
  49. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  50. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +27 -0
  51. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  52. package/src/plugins/bundling/css/bundle_css.js +140 -0
  53. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  54. package/src/plugins/bundling/js_module/bundle_js_module.js +309 -0
  55. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  56. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +34 -0
  57. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  58. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  59. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  61. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  62. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +242 -0
  63. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  64. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  65. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  66. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +83 -61
  67. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  68. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  69. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  70. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +7 -4
  71. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +105 -0
  72. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  73. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  74. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  75. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +39 -33
  76. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  77. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  78. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  79. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +65 -44
  80. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  81. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  82. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +297 -0
  83. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  84. package/src/plugins/minification/css/minify_css.js +9 -0
  85. package/src/plugins/minification/html/minify_html.js +15 -0
  86. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  87. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  88. package/src/plugins/minification/json/minify_json.js +8 -0
  89. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  90. package/src/{omega → plugins}/plugin_controller.js +42 -11
  91. package/src/plugins/plugins.js +92 -0
  92. package/src/plugins/transpilation/as_js_classic/client/s.js +874 -0
  93. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  94. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  95. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  96. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +199 -0
  97. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +270 -0
  98. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +55 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +12 -19
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +45 -27
  105. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  106. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  107. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  108. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  109. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  110. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  111. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  112. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +181 -0
  113. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +80 -0
  114. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  115. package/src/plugins/url_analysis/css/css_urls.js +49 -0
  116. package/src/plugins/url_analysis/html/html_urls.js +269 -0
  117. package/src/plugins/url_analysis/js/js_urls.js +67 -0
  118. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +18 -0
  119. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +17 -0
  120. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  121. package/src/plugins/url_version/jsenv_plugin_url_version.js +28 -0
  122. package/src/test/execute_plan.js +38 -19
  123. package/src/test/execute_test_plan.js +25 -8
  124. package/src/test/logs_file_execution.js +10 -12
  125. package/src/build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js +0 -225
  126. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  127. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  128. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  129. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  130. package/src/execute/runtimes/node/controlled_process.js +0 -316
  131. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  132. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  133. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  134. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  135. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  136. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  137. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  138. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  139. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  140. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  141. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  142. package/src/omega/core_plugins/url_version/jsenv_plugin_url_version.js +0 -50
  143. package/src/omega/core_plugins.js +0 -39
  144. package/src/omega/runtime_support/runtime_support.js +0 -20
  145. package/src/omega/url_graph/url_graph_sort.js +0 -29
  146. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  147. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  148. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  149. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  150. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -1,51 +1,52 @@
1
1
  import {
2
2
  urlIsInsideOf,
3
3
  writeFileSync,
4
- isFileSystemPath,
5
- fileSystemPathToUrl,
6
4
  moveUrl,
7
- fileSystemRootUrl,
5
+ ensureWindowsDriveLetter,
8
6
  } from "@jsenv/filesystem"
7
+ import { createDetailedMessage } from "@jsenv/logger"
9
8
 
9
+ import { getCallerPosition } from "@jsenv/utils/src/caller_position.js"
10
10
  import { stringifyUrlSite } from "@jsenv/utils/urls/url_trace.js"
11
+ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
12
+ import { normalizeUrl, setUrlFilename } from "@jsenv/utils/urls/url_utils.js"
11
13
 
14
+ import { createPluginController } from "../plugins/plugin_controller.js"
12
15
  import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
13
- import { featuresCompatMap } from "./runtime_support/features_compatibility.js"
14
- import { isFeatureSupportedOnRuntimes } from "./runtime_support/runtime_support.js"
15
- import { fileUrlConverter } from "./file_url_converter.js"
16
- import { parseUrlMentions } from "./url_mentions/parse_url_mentions.js"
16
+ import { RUNTIME_COMPAT } from "./compat/runtime_compat.js"
17
+ import { defaultRuntimeCompat } from "./compat/default_runtime_compat.js"
17
18
  import {
18
- createResolveError,
19
- createLoadError,
20
- createParseError,
21
- createTransformError,
19
+ createResolveUrlError,
20
+ createFetchUrlContentError,
21
+ createTransformUrlContentError,
22
+ createFinalizeUrlContentError,
22
23
  } from "./errors.js"
23
- import { createPluginController } from "./plugin_controller.js"
24
+ import { assertFetchedContentCompliance } from "./fetched_content_compliance.js"
25
+ import { isWebWorkerEntryPointReference } from "./web_workers.js"
24
26
 
25
27
  export const createKitchen = ({
26
28
  signal,
27
29
  logger,
28
30
  rootDirectoryUrl,
29
31
  urlGraph,
32
+
30
33
  plugins,
31
34
  scenario,
32
-
33
35
  sourcemaps = {
34
36
  dev: "inline", // "programmatic" and "file" also allowed
35
37
  test: "inline",
36
38
  build: "none",
37
39
  }[scenario],
38
- // we don't need sources in sourcemap as long as the url in the
39
- // sourcemap uses file:/// (chrome will understand and read from filesystem)
40
- sourcemapsSources = false,
41
- loadInlineUrlInfos = (urlInfo) => {
42
- return {
43
- contentType: urlInfo.contentType,
44
- content: urlInfo.content,
45
- }
46
- },
47
-
48
- writeOnFileSystem = true,
40
+ sourcemapsSourcesContent = {
41
+ // during dev/test, chrome is able to find the sourcemap sources
42
+ // as long as they use file:// protocol in the sourcemap files
43
+ dev: false,
44
+ test: false,
45
+ build: true,
46
+ }[scenario],
47
+ sourcemapsRelativeSources,
48
+ runtimeCompat = defaultRuntimeCompat,
49
+ writeGeneratedFiles,
49
50
  }) => {
50
51
  const pluginController = createPluginController({
51
52
  plugins,
@@ -59,105 +60,168 @@ export const createKitchen = ({
59
60
  sourcemaps,
60
61
  urlGraph,
61
62
  scenario,
63
+ runtimeCompat,
64
+ isSupportedOnFutureClients: (feature) => {
65
+ return RUNTIME_COMPAT.isSupported(runtimeCompat, feature)
66
+ },
62
67
  }
63
68
  const createReference = ({
64
69
  data = {},
70
+ node,
65
71
  trace,
66
72
  parentUrl,
67
73
  type,
68
74
  subtype,
75
+ expectedContentType,
76
+ expectedType,
77
+ expectedSubtype,
78
+ filename,
79
+ integrity,
80
+ crossorigin,
69
81
  specifier,
82
+ specifierStart,
83
+ specifierEnd,
84
+ specifierLine,
85
+ specifierColumn,
86
+ baseUrl,
87
+ isOriginalPosition,
88
+ external = false,
70
89
  isInline = false,
90
+ injected = false,
91
+ isRessourceHint = false,
71
92
  content,
72
93
  contentType,
94
+ assert,
95
+ assertNode,
96
+ typePropertyNode,
73
97
  }) => {
98
+ if (typeof specifier !== "string") {
99
+ throw new TypeError(`"specifier" must be a string, got ${specifier}`)
100
+ }
74
101
  return {
102
+ original: null,
103
+ prev: null,
104
+ next: null,
75
105
  data,
106
+ node,
76
107
  trace,
77
108
  parentUrl,
78
109
  type,
79
110
  subtype,
111
+ expectedContentType,
112
+ expectedType,
113
+ expectedSubtype,
114
+ filename,
115
+ integrity,
116
+ crossorigin,
80
117
  specifier,
118
+ specifierStart,
119
+ specifierEnd,
120
+ specifierLine,
121
+ specifierColumn,
122
+ baseUrl,
123
+ isOriginalPosition,
124
+ external,
81
125
  isInline,
126
+ injected,
127
+ isRessourceHint,
82
128
  // for inline ressources the reference contains the content
83
129
  content,
84
130
  contentType,
131
+ timing: {},
132
+ assert,
133
+ assertNode,
134
+ typePropertyNode,
85
135
  }
86
136
  }
137
+ const mutateReference = (reference, newReference) => {
138
+ reference.next = newReference
139
+ newReference.prev = reference
140
+ newReference.original = reference.original || reference
141
+ }
87
142
  const resolveReference = (reference) => {
88
143
  try {
89
- const resolvedUrl = pluginController.callHooksUntil(
90
- "resolve",
144
+ let resolvedUrl = pluginController.callHooksUntil(
145
+ "resolveUrl",
91
146
  reference,
92
147
  baseContext,
93
148
  )
94
149
  if (!resolvedUrl) {
95
150
  throw new Error(`NO_RESOLVE`)
96
151
  }
152
+ resolvedUrl = normalizeUrl(resolvedUrl)
97
153
  reference.url = resolvedUrl
154
+ if (reference.external) {
155
+ reference.generatedUrl = resolvedUrl
156
+ reference.generatedSpecifier = reference.specifier
157
+ return urlGraph.reuseOrCreateUrlInfo(reference.url)
158
+ }
98
159
  pluginController.callHooks(
99
- "normalize",
160
+ "redirectUrl",
100
161
  reference,
101
162
  baseContext,
102
163
  (returnValue) => {
103
- reference.url = returnValue
164
+ const normalizedReturnValue = normalizeUrl(returnValue)
165
+ if (normalizedReturnValue === reference.url) {
166
+ return
167
+ }
168
+ const previousReference = { ...reference }
169
+ reference.url = normalizedReturnValue
170
+ mutateReference(previousReference, reference)
104
171
  },
105
172
  )
106
- // force a last normalization regarding on url search params
107
- // some plugin use URLSearchParams to alter the url search params
108
- // which can result into "file:///file.css?css_module"
109
- // becoming "file:///file.css?css_module="
110
- // we want to get rid of the "=" and consider it's the same url
111
- if (
112
- // disable on data urls (would mess up base64 encoding)
113
- !reference.url.startsWith("data:")
114
- ) {
115
- reference.url = reference.url.replace(/[=](?=&|$)/g, "")
116
- }
173
+
117
174
  const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url)
118
- Object.assign(urlInfo.data, reference.data)
175
+ applyReferenceEffectsOnUrlInfo(reference, urlInfo, baseContext)
119
176
 
120
- // create a copy because .url will be mutated
121
- const referencedCopy = {
122
- ...reference,
123
- data: urlInfo.data,
124
- }
177
+ const referenceUrlObject = new URL(reference.url)
178
+ reference.searchParams = referenceUrlObject.searchParams
179
+ reference.generatedUrl = reference.url
180
+ // This hook must touch reference.generatedUrl, NOT reference.url
181
+ // And this is because this hook inject query params used to:
182
+ // - bypass browser cache (?v)
183
+ // - convey information (?hmr)
184
+ // But do not represent an other ressource, it is considered as
185
+ // the same ressource under the hood
125
186
  pluginController.callHooks(
126
- "transformReferencedUrl",
127
- referencedCopy,
187
+ "transformUrlSearchParams",
188
+ reference,
128
189
  baseContext,
129
190
  (returnValue) => {
130
- referencedCopy.url = returnValue
191
+ Object.keys(returnValue).forEach((key) => {
192
+ referenceUrlObject.searchParams.set(key, returnValue[key])
193
+ })
194
+ reference.generatedUrl = normalizeUrl(referenceUrlObject.href)
131
195
  },
132
196
  )
133
- reference.generatedUrl = referencedCopy.url
134
197
  const returnValue = pluginController.callHooksUntil(
135
- "formatReferencedUrl",
136
- referencedCopy,
198
+ "formatUrl",
199
+ reference,
137
200
  baseContext,
138
201
  )
139
202
  reference.generatedSpecifier = returnValue || reference.generatedUrl
140
- reference.generatedSpecifier = specifierFormat.encode(reference)
203
+ reference.generatedSpecifier = urlSpecifierFormat.encode(reference)
141
204
  return urlInfo
142
205
  } catch (error) {
143
- throw createResolveError({
206
+ throw createResolveUrlError({
144
207
  pluginController,
145
208
  reference,
146
209
  error,
147
210
  })
148
211
  }
149
212
  }
213
+ baseContext.resolveReference = resolveReference
150
214
  const urlInfoTransformer = createUrlInfoTransformer({
151
215
  logger,
152
216
  urlGraph,
153
217
  sourcemaps,
154
- sourcemapsSources,
218
+ sourcemapsSourcesContent,
219
+ sourcemapsRelativeSources,
155
220
  injectSourcemapPlaceholder: ({ urlInfo, specifier }) => {
156
221
  const sourcemapReference = createReference({
157
222
  trace: `sourcemap comment placeholder for ${urlInfo.url}`,
158
223
  type: "sourcemap_comment",
159
- subtype:
160
- urlInfo.contentType === "application/javascript" ? "js" : "css",
224
+ subtype: urlInfo.contentType === "text/javascript" ? "js" : "css",
161
225
  parentUrl: urlInfo.url,
162
226
  specifier,
163
227
  })
@@ -165,19 +229,27 @@ export const createKitchen = ({
165
229
  sourcemapUrlInfo.type = "sourcemap"
166
230
  return [sourcemapReference, sourcemapUrlInfo]
167
231
  },
168
- foundSourcemap: ({ urlInfo, line, column, type, specifier }) => {
232
+ foundSourcemap: ({
233
+ urlInfo,
234
+ type,
235
+ specifier,
236
+ specifierLine,
237
+ specifierColumn,
238
+ }) => {
169
239
  const sourcemapReference = createReference({
170
240
  trace: stringifyUrlSite(
171
241
  adjustUrlSite(urlInfo, {
172
242
  urlGraph,
173
243
  url: urlInfo.url,
174
- line,
175
- column,
244
+ line: specifierLine,
245
+ column: specifierColumn,
176
246
  }),
177
247
  ),
178
248
  type,
179
249
  parentUrl: urlInfo.url,
180
250
  specifier,
251
+ specifierLine,
252
+ specifierColumn,
181
253
  })
182
254
  const sourcemapUrlInfo = resolveReference(sourcemapReference)
183
255
  sourcemapUrlInfo.type = "sourcemap"
@@ -185,69 +257,78 @@ export const createKitchen = ({
185
257
  },
186
258
  })
187
259
 
188
- const isSupported = ({
189
- runtimeSupport,
190
- featureName,
191
- featureCompat = featuresCompatMap[featureName],
192
- }) => {
193
- return isFeatureSupportedOnRuntimes(runtimeSupport, featureCompat)
194
- }
195
-
196
- const load = async ({ reference, urlInfo, context }) => {
260
+ const fetchUrlContent = async ({ reference, urlInfo, context }) => {
261
+ if (reference.external) {
262
+ urlInfo.external = true
263
+ return
264
+ }
197
265
  try {
198
- const loadReturnValue = urlInfo.isInline
199
- ? loadInlineUrlInfos(urlInfo)
200
- : await pluginController.callAsyncHooksUntil("load", urlInfo, context)
201
- if (!loadReturnValue) {
202
- throw new Error("NO_LOAD")
266
+ const fetchUrlContentReturnValue =
267
+ await pluginController.callAsyncHooksUntil(
268
+ "fetchUrlContent",
269
+ urlInfo,
270
+ context,
271
+ )
272
+ if (!fetchUrlContentReturnValue) {
273
+ logger.warn(
274
+ createDetailedMessage(
275
+ `no plugin has handled the url during "fetchUrlContent" hook -> consider url as external (ignore it)`,
276
+ {
277
+ "url": urlInfo.url,
278
+ "url reference trace": reference.trace,
279
+ },
280
+ ),
281
+ )
282
+ urlInfo.external = true
283
+ return
284
+ }
285
+ if (fetchUrlContentReturnValue.external) {
286
+ urlInfo.external = true
287
+ return
203
288
  }
204
-
205
289
  const {
206
- contentType = "application/octet-stream",
207
- content, // can be a buffer (used for binary files) or a string
208
- sourcemap,
209
- // during build urls info are reused and load returns originalContent
210
- // that we want to keep
211
- originalContent = content,
212
290
  data,
213
- } = loadReturnValue
214
- Object.assign(urlInfo, {
215
- contentType,
291
+ type,
292
+ subtype,
293
+ contentType = "application/octet-stream",
216
294
  originalContent,
217
295
  content,
218
296
  sourcemap,
219
- })
297
+ filename,
298
+ } = fetchUrlContentReturnValue
299
+ urlInfo.type =
300
+ type ||
301
+ reference.expectedType ||
302
+ inferUrlInfoType({
303
+ url: urlInfo.url,
304
+ contentType,
305
+ })
306
+ urlInfo.subtype =
307
+ subtype ||
308
+ reference.expectedSubtype ||
309
+ inferUrlInfoSubtype({
310
+ url: urlInfo.url,
311
+ type: urlInfo.type,
312
+ subtype: urlInfo.subtype,
313
+ })
314
+ urlInfo.contentType = contentType
315
+ // during build urls info are reused and load returns originalContent
316
+ urlInfo.originalContent =
317
+ originalContent === undefined ? content : originalContent
318
+ urlInfo.content = content
319
+ urlInfo.sourcemap = sourcemap
220
320
  if (data) {
221
321
  Object.assign(urlInfo.data, data)
222
322
  }
223
- if (!urlInfo.type) {
224
- const type = inferUrlInfoType(urlInfo)
225
- if (type === "js") {
226
- const urlObject = new URL(urlInfo.url)
227
- if (urlObject.searchParams.has("worker_type_classic")) {
228
- urlInfo.type = "js_classic"
229
- urlInfo.subtype = "worker"
230
- } else if (
231
- urlObject.searchParams.has("service_worker_type_classic")
232
- ) {
233
- urlInfo.type = "js_classic"
234
- urlInfo.subtype = "service_worker"
235
- } else if (urlObject.searchParams.has("js_classic")) {
236
- urlInfo.type = "js_classic"
237
- } else {
238
- urlInfo.type = "js_module"
239
- }
240
- if (urlObject.searchParams.has("worker")) {
241
- urlInfo.subtype = "worker"
242
- } else if (urlObject.searchParams.has("service_worker")) {
243
- urlInfo.subtype = "service_worker"
244
- }
245
- } else {
246
- urlInfo.type = type
247
- }
323
+ if (filename) {
324
+ urlInfo.filename = filename
248
325
  }
326
+ assertFetchedContentCompliance({
327
+ reference,
328
+ urlInfo,
329
+ })
249
330
  } catch (error) {
250
- throw createLoadError({
331
+ throw createFetchUrlContentError({
251
332
  pluginController,
252
333
  urlInfo,
253
334
  reference,
@@ -255,9 +336,8 @@ export const createKitchen = ({
255
336
  })
256
337
  }
257
338
  urlInfo.generatedUrl = determineFileUrlForOutDirectory({
258
- rootDirectoryUrl,
259
- outDirectoryUrl: context.outDirectoryUrl,
260
- url: urlInfo.url,
339
+ urlInfo,
340
+ context,
261
341
  })
262
342
  await urlInfoTransformer.initTransformations(urlInfo, context)
263
343
  }
@@ -266,34 +346,39 @@ export const createKitchen = ({
266
346
  reference,
267
347
  urlInfo,
268
348
  outDirectoryUrl,
269
- runtimeSupport,
349
+ // during dev/test clientRuntimeCompat is a single runtime
350
+ // during build clientRuntimeCompat is runtimeCompat
351
+ clientRuntimeCompat = runtimeCompat,
270
352
  cookDuringCook = cook,
271
353
  }) => {
354
+ baseContext.isSupportedOnCurrentClients = (feature) => {
355
+ return RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature)
356
+ }
272
357
  const context = {
273
358
  ...baseContext,
274
359
  reference,
275
360
  outDirectoryUrl,
276
- runtimeSupport,
277
- isSupportedOnRuntime: (featureName, featureCompat) => {
278
- return isSupported({ runtimeSupport, featureName, featureCompat })
279
- },
361
+ clientRuntimeCompat,
280
362
  cook: (params) => {
281
363
  return cookDuringCook({
282
364
  outDirectoryUrl,
283
- runtimeSupport,
365
+ clientRuntimeCompat,
284
366
  ...params,
285
367
  })
286
368
  },
287
- load: (params) => {
288
- return load({
369
+ fetchUrlContent: (params) => {
370
+ return fetchUrlContent({
289
371
  context,
290
372
  ...params,
291
373
  })
292
374
  },
293
375
  }
294
376
 
295
- // "load" hook
296
- await load({ reference, urlInfo, context })
377
+ // "fetchUrlContent" hook
378
+ await fetchUrlContent({ reference, urlInfo, context })
379
+ if (urlInfo.external) {
380
+ return
381
+ }
297
382
 
298
383
  // parsing
299
384
  const references = []
@@ -303,182 +388,145 @@ export const createKitchen = ({
303
388
  ...props,
304
389
  })
305
390
  references.push(reference)
306
- return [reference, resolveReference(reference)]
391
+ const referencedUrlInfo = resolveReference(reference)
392
+ return [reference, referencedUrlInfo]
307
393
  }
308
394
  const referenceUtils = {
309
- inject: ({ trace, ...rest }) => {
310
- if (trace === undefined) {
311
- const { prepareStackTrace } = Error
312
- Error.prepareStackTrace = (error, stack) => {
313
- Error.prepareStackTrace = prepareStackTrace
314
- return stack
315
- }
316
- const { stack } = new Error()
317
- const callerCallsite = stack[1]
318
- const fileName = callerCallsite.getFileName()
319
- trace = stringifyUrlSite({
320
- url:
321
- fileName && isFileSystemPath(fileName)
322
- ? fileSystemPathToUrl(fileName)
323
- : fileName,
324
- line: callerCallsite.getLineNumber(),
325
- column: callerCallsite.getColumnNumber(),
395
+ readGeneratedSpecifier: async (reference) => {
396
+ // "formatReferencedUrl" can be async BUT this is an exception
397
+ // for most cases it will be sync. We want to favor the sync signature to keep things simpler
398
+ // The only case where it needs to be async is when
399
+ // the specifier is a `data:*` url
400
+ // in this case we'll wait for the promise returned by
401
+ // "formatReferencedUrl"
402
+ if (reference.generatedSpecifier.then) {
403
+ return reference.generatedSpecifier.then((value) => {
404
+ reference.generatedSpecifier = value
405
+ return value
326
406
  })
327
407
  }
408
+ return reference.generatedSpecifier
409
+ },
410
+ found: ({ specifierLine, specifierColumn, ...rest }) => {
411
+ const trace = stringifyUrlSite(
412
+ adjustUrlSite(urlInfo, {
413
+ urlGraph,
414
+ url: urlInfo.url,
415
+ line: specifierLine,
416
+ column: specifierColumn,
417
+ }),
418
+ )
419
+ // console.log(trace)
328
420
  return addReference({
329
421
  trace,
422
+ specifierLine,
423
+ specifierColumn,
330
424
  ...rest,
331
425
  })
332
426
  },
333
- foundInline: ({
334
- type,
335
- isOriginal,
336
- line,
337
- column,
338
- specifier,
339
- contentType,
340
- content,
341
- }) => {
342
- const parentUrl = isOriginal ? urlInfo.url : urlInfo.generatedUrl
343
- const parentContent = isOriginal
427
+ foundInline: ({ isOriginalPosition, line, column, ...rest }) => {
428
+ const parentUrl = isOriginalPosition
429
+ ? urlInfo.url
430
+ : urlInfo.generatedUrl
431
+ const parentContent = isOriginalPosition
344
432
  ? urlInfo.originalContent
345
433
  : urlInfo.content
346
- const [inlineReference, inlineUrlInfo] = addReference({
434
+ return addReference({
347
435
  trace: stringifyUrlSite({
348
436
  url: parentUrl,
349
437
  content: parentContent,
350
438
  line,
351
439
  column,
352
440
  }),
353
- type,
354
- specifier,
355
- isInline: true,
356
- contentType,
357
- content,
358
- })
359
- inlineUrlInfo.isInline = true
360
- inlineUrlInfo.inlineUrlSite = {
361
- url: urlInfo.url,
362
- content: parentContent,
441
+ isOriginalPosition,
363
442
  line,
364
443
  column,
365
- }
366
- inlineUrlInfo.contentType = contentType
367
- inlineUrlInfo.originalContent = inlineUrlInfo.content = content
368
- return [inlineReference, inlineUrlInfo]
444
+ isInline: true,
445
+ ...rest,
446
+ })
369
447
  },
370
- updateSpecifier: (generatedSpecifier, newSpecifier, data) => {
371
- const index = references.findIndex(
372
- (ref) => ref.generatedSpecifier === generatedSpecifier,
373
- )
448
+ update: (currentReference, newReferenceParams) => {
449
+ const index = references.indexOf(currentReference)
374
450
  if (index === -1) {
375
- throw new Error(
376
- `Cannot find a reference for the following generatedSpecifier "${generatedSpecifier}"`,
377
- )
451
+ throw new Error(`reference do not exists`)
378
452
  }
379
- const referenceFound = references[index]
380
- const newReference = createReference({
381
- ...referenceFound,
382
- specifier: newSpecifier,
383
- data: {
384
- ...referenceFound.data,
385
- ...data,
386
- },
453
+ const previousReference = currentReference
454
+ const nextReference = createReference({
455
+ ...previousReference,
456
+ ...newReferenceParams,
387
457
  })
388
- references[index] = newReference
389
- newReference.data.originalReference = referenceFound
390
- const newUrlInfo = resolveReference(newReference)
391
- return [newReference, newUrlInfo]
458
+ references[index] = nextReference
459
+ mutateReference(previousReference, nextReference)
460
+ const newUrlInfo = resolveReference(nextReference)
461
+ const currentUrlInfo = context.urlGraph.getUrlInfo(currentReference.url)
462
+ if (
463
+ currentUrlInfo &&
464
+ currentUrlInfo !== newUrlInfo &&
465
+ currentUrlInfo.dependents.size === 0
466
+ ) {
467
+ context.urlGraph.deleteUrlInfo(currentReference.url)
468
+ }
469
+ return [nextReference, newUrlInfo]
392
470
  },
393
471
  becomesInline: (
394
472
  reference,
395
- { isOriginal, line, column, specifier, contentType, content },
473
+ {
474
+ isOriginalPosition,
475
+ specifier,
476
+ specifierLine,
477
+ specifierColumn,
478
+ contentType,
479
+ content,
480
+ },
396
481
  ) => {
397
- const parentUrl = isOriginal ? urlInfo.url : urlInfo.generatedUrl
398
- const parentContent = isOriginal
482
+ const parentUrl = isOriginalPosition
483
+ ? urlInfo.url
484
+ : urlInfo.generatedUrl
485
+ const parentContent = isOriginalPosition
399
486
  ? urlInfo.originalContent
400
487
  : urlInfo.content
401
- reference.trace = stringifyUrlSite({
402
- url: parentUrl,
403
- content: parentContent,
404
- line,
405
- column,
488
+ return referenceUtils.update(reference, {
489
+ trace: stringifyUrlSite({
490
+ url: parentUrl,
491
+ content: parentContent,
492
+ line: specifierLine,
493
+ column: specifierColumn,
494
+ }),
495
+ isOriginalPosition,
496
+ isInline: true,
497
+ specifier,
498
+ specifierLine,
499
+ specifierColumn,
500
+ contentType,
501
+ content,
406
502
  })
407
- reference.isInline = true
408
- reference.specifier = specifier
409
- reference.contentType = contentType
410
- reference.content = content
411
- const inlineUrlInfo = resolveReference(reference)
412
- inlineUrlInfo.isInline = true
413
- inlineUrlInfo.inlineUrlSite = {
414
- url: urlInfo.url,
415
- content: parentContent,
416
- line,
417
- column,
418
- }
419
- inlineUrlInfo.contentType = contentType
420
- inlineUrlInfo.content = content
421
- return reference
422
503
  },
423
- }
424
-
425
- let parseResult
426
- try {
427
- parseResult = await parseUrlMentions({
428
- type: urlInfo.type,
429
- url: urlInfo.data.sourceUrl || urlInfo.url,
430
- generatedUrl: urlInfo.generatedUrl,
431
- content: urlInfo.content,
432
- })
433
- } catch (error) {
434
- throw createParseError({
435
- reference,
436
- urlInfo,
437
- error,
438
- })
439
- }
440
- if (parseResult) {
441
- Object.assign(urlInfo.data, parseResult.data)
442
- const { urlMentions, replaceUrls } = parseResult
443
- for (const urlMention of urlMentions) {
444
- const [reference] = addReference({
445
- trace: stringifyUrlSite(
446
- adjustUrlSite(urlInfo, {
447
- urlGraph,
448
- url: urlInfo.url,
449
- line: urlMention.line,
450
- column: urlMention.column,
451
- }),
452
- ),
453
- type: urlMention.type,
454
- subtype: urlMention.subtype,
455
- specifier: urlMention.specifier,
456
- })
457
- urlMention.reference = reference
458
- }
459
- if (references.length) {
460
- // "formatReferencedUrl" can be async BUT this is an exception
461
- // for most cases it will be sync. We want to favor the sync signature to keep things simpler
462
- // The only case where it needs to be async is when
463
- // the specifier is a `data:*` url
464
- // in this case we'll wait for the promise returned by
465
- // "formatReferencedUrl"
466
- await Promise.all(
467
- references.map(async (reference) => {
468
- if (reference.generatedSpecifier.then) {
469
- const value = await reference.generatedSpecifier
470
- reference.generatedSpecifier = value
471
- }
472
- }),
473
- )
474
- const replaceReturnValue = await replaceUrls((urlMention) => {
475
- return urlMention.reference.generatedSpecifier
504
+ inject: ({ trace, ...rest }) => {
505
+ if (trace === undefined) {
506
+ const { url, line, column } = getCallerPosition()
507
+ trace = stringifyUrlSite({
508
+ url,
509
+ line,
510
+ column,
511
+ })
512
+ }
513
+ return addReference({
514
+ trace,
515
+ injected: true,
516
+ ...rest,
476
517
  })
477
- await urlInfoTransformer.applyIntermediateTransformations(
478
- urlInfo,
479
- replaceReturnValue,
518
+ },
519
+ findByGeneratedSpecifier: (generatedSpecifier) => {
520
+ const reference = references.find(
521
+ (ref) => ref.generatedSpecifier === generatedSpecifier,
480
522
  )
481
- }
523
+ if (!reference) {
524
+ throw new Error(
525
+ `No reference found using the following generatedSpecifier: "${generatedSpecifier}"`,
526
+ )
527
+ }
528
+ return reference
529
+ },
482
530
  }
483
531
 
484
532
  // "transform" hook
@@ -486,7 +534,7 @@ export const createKitchen = ({
486
534
  context.referenceUtils = referenceUtils
487
535
  try {
488
536
  await pluginController.callAsyncHooks(
489
- "transform",
537
+ "transformUrlContent",
490
538
  urlInfo,
491
539
  context,
492
540
  async (transformReturnValue) => {
@@ -497,7 +545,7 @@ export const createKitchen = ({
497
545
  },
498
546
  )
499
547
  } catch (error) {
500
- throw createTransformError({
548
+ throw createTransformUrlContentError({
501
549
  pluginController,
502
550
  reference,
503
551
  urlInfo,
@@ -509,15 +557,24 @@ export const createKitchen = ({
509
557
  urlGraph.updateReferences(urlInfo, references)
510
558
 
511
559
  // "finalize" hook
512
- const finalizeReturnValue = await pluginController.callHooksUntil(
513
- "finalize",
514
- urlInfo,
515
- context,
516
- )
517
- await urlInfoTransformer.applyFinalTransformations(
518
- urlInfo,
519
- finalizeReturnValue,
520
- )
560
+ try {
561
+ const finalizeReturnValue = await pluginController.callAsyncHooksUntil(
562
+ "finalizeUrlContent",
563
+ urlInfo,
564
+ context,
565
+ )
566
+ await urlInfoTransformer.applyFinalTransformations(
567
+ urlInfo,
568
+ finalizeReturnValue,
569
+ )
570
+ } catch (error) {
571
+ throw createFinalizeUrlContentError({
572
+ pluginController,
573
+ reference,
574
+ urlInfo,
575
+ error,
576
+ })
577
+ }
521
578
 
522
579
  // "cooked" hook
523
580
  pluginController.callHooks(
@@ -541,11 +598,11 @@ export const createKitchen = ({
541
598
  },
542
599
  )
543
600
  }
544
- const cook = async ({ urlInfo, outDirectoryUrl, ...rest }) => {
601
+ const cook = memoizeCook(async ({ urlInfo, outDirectoryUrl, ...rest }) => {
545
602
  outDirectoryUrl = outDirectoryUrl ? String(outDirectoryUrl) : undefined
546
603
 
547
604
  const writeFiles = ({ gotError }) => {
548
- if (!writeOnFileSystem || !outDirectoryUrl) {
605
+ if (!writeGeneratedFiles || !outDirectoryUrl) {
549
606
  return
550
607
  }
551
608
  const { generatedUrl } = urlInfo
@@ -576,19 +633,96 @@ export const createKitchen = ({
576
633
  writeFiles({ gotError: true })
577
634
  throw e
578
635
  }
579
- }
636
+ })
580
637
 
581
638
  baseContext.cook = cook
582
639
 
640
+ const prepareEntryPoint = (params) => {
641
+ const entryReference = createReference(params)
642
+ const entryUrlInfo = resolveReference(entryReference)
643
+ return [entryReference, entryUrlInfo]
644
+ }
645
+
646
+ const injectReference = (params) => {
647
+ const ref = createReference(params)
648
+ const urlInfo = resolveReference(ref)
649
+ return [ref, urlInfo]
650
+ }
651
+
583
652
  return {
584
653
  pluginController,
585
654
  urlInfoTransformer,
586
655
  rootDirectoryUrl,
587
656
  jsenvDirectoryUrl,
588
- isSupported,
589
- createReference,
590
- resolveReference,
657
+ baseContext,
591
658
  cook,
659
+ prepareEntryPoint,
660
+ injectReference,
661
+ }
662
+ }
663
+
664
+ const memoizeCook = (cook) => {
665
+ const pendingDishes = new Map()
666
+ return async (params) => {
667
+ const { urlInfo } = params
668
+ const { url, modifiedTimestamp } = urlInfo
669
+ const pendingDish = pendingDishes.get(url)
670
+ if (pendingDish) {
671
+ if (!modifiedTimestamp) {
672
+ await pendingDish.promise
673
+ return
674
+ }
675
+ if (pendingDish.timestamp > modifiedTimestamp) {
676
+ await pendingDish.promise
677
+ return
678
+ }
679
+ pendingDishes.delete(url)
680
+ }
681
+ const timestamp = Date.now()
682
+ const promise = cook(params)
683
+ pendingDishes.set(url, {
684
+ timestamp,
685
+ promise,
686
+ })
687
+ try {
688
+ await promise
689
+ } finally {
690
+ pendingDishes.delete(url)
691
+ }
692
+ }
693
+ }
694
+
695
+ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
696
+ Object.assign(urlInfo.data, reference.data)
697
+ Object.assign(urlInfo.timing, reference.timing)
698
+ if (reference.injected) {
699
+ urlInfo.data.injected = true
700
+ }
701
+ if (reference.filename) {
702
+ urlInfo.filename = reference.filename
703
+ }
704
+ if (reference.isInline) {
705
+ urlInfo.isInline = true
706
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
707
+ urlInfo.inlineUrlSite = {
708
+ url: parentUrlInfo.url,
709
+ content: reference.isOriginalPosition
710
+ ? parentUrlInfo.originalContent
711
+ : parentUrlInfo.content,
712
+ line: reference.specifierLine,
713
+ column: reference.specifierColumn,
714
+ }
715
+ urlInfo.contentType = reference.contentType
716
+ urlInfo.originalContent =
717
+ context === "build"
718
+ ? urlInfo.originalContent === undefined
719
+ ? reference.content
720
+ : urlInfo.originalContent
721
+ : reference.content
722
+ urlInfo.content = reference.content
723
+ }
724
+ if (isWebWorkerEntryPointReference(reference)) {
725
+ urlInfo.data.isWebWorkerEntryPoint = true
592
726
  }
593
727
  }
594
728
 
@@ -626,54 +760,86 @@ const adjustUrlSite = (urlInfo, { urlGraph, url, line, column }) => {
626
760
  )
627
761
  }
628
762
 
629
- const inferUrlInfoType = ({ contentType }) => {
763
+ const inferUrlInfoType = ({ url, contentType }) => {
630
764
  if (contentType === "text/html") {
631
765
  return "html"
632
766
  }
633
767
  if (contentType === "text/css") {
634
768
  return "css"
635
769
  }
636
- if (contentType === "application/javascript") {
637
- return "js"
638
- }
639
- if (contentType === "application/json") {
640
- return "json"
770
+ if (contentType === "text/javascript") {
771
+ const urlObject = new URL(url)
772
+ if (urlObject.searchParams.has("js_classic")) {
773
+ return "js_classic"
774
+ }
775
+ return "js_module"
641
776
  }
642
777
  if (contentType === "application/importmap+json") {
643
778
  return "importmap"
644
779
  }
780
+ if (contentType === "application/manifest+json") {
781
+ return "webmanifest"
782
+ }
783
+ if (contentType === "image/svg+xml") {
784
+ return "svg"
785
+ }
786
+ if (CONTENT_TYPE.isJson(contentType)) {
787
+ return "json"
788
+ }
789
+ if (CONTENT_TYPE.isTextual(contentType)) {
790
+ return "text"
791
+ }
645
792
  return "other"
646
793
  }
647
794
 
648
- const determineFileUrlForOutDirectory = ({
649
- rootDirectoryUrl,
650
- outDirectoryUrl,
651
- url,
652
- }) => {
653
- if (!outDirectoryUrl) {
654
- return url
795
+ const inferUrlInfoSubtype = ({ type, subtype, url }) => {
796
+ if (type === "js_classic" || type === "js_module") {
797
+ const urlObject = new URL(url)
798
+ if (urlObject.searchParams.has("worker")) {
799
+ return "worker"
800
+ }
801
+ if (urlObject.searchParams.has("service_worker")) {
802
+ return "service_worker"
803
+ }
804
+ if (urlObject.searchParams.has("shared_worker")) {
805
+ return "shared_worker"
806
+ }
807
+ // if we are currently inside a worker, all deps are consider inside worker too
808
+ return subtype
809
+ }
810
+ return ""
811
+ }
812
+
813
+ const determineFileUrlForOutDirectory = ({ urlInfo, context }) => {
814
+ if (!context.outDirectoryUrl) {
815
+ return urlInfo.url
816
+ }
817
+ if (!urlInfo.url.startsWith("file:")) {
818
+ return urlInfo.url
655
819
  }
656
- if (!url.startsWith("file:")) {
657
- return url
820
+ let url = urlInfo.url
821
+ if (!urlIsInsideOf(urlInfo.url, context.rootDirectoryUrl)) {
822
+ const fsRootUrl = ensureWindowsDriveLetter("file:///", urlInfo.url)
823
+ url = `${context.rootDirectoryUrl}@fs/${url.slice(fsRootUrl.length)}`
658
824
  }
659
- if (!urlIsInsideOf(url, rootDirectoryUrl)) {
660
- url = `${rootDirectoryUrl}@fs/${url.slice(fileSystemRootUrl.length)}`
825
+ if (urlInfo.filename) {
826
+ url = setUrlFilename(url, urlInfo.filename)
661
827
  }
662
828
  return moveUrl({
663
- url: fileUrlConverter.asUrlWithoutSpecialParams(url),
664
- from: rootDirectoryUrl,
665
- to: outDirectoryUrl,
829
+ url,
830
+ from: context.rootDirectoryUrl,
831
+ to: context.outDirectoryUrl,
666
832
  preferAbsolute: true,
667
833
  })
668
834
  }
669
835
 
670
- const specifierFormat = {
836
+ const urlSpecifierFormat = {
671
837
  encode: (reference) => {
672
838
  const { generatedSpecifier } = reference
673
839
  if (generatedSpecifier.then) {
674
840
  return generatedSpecifier.then((value) => {
675
841
  reference.generatedSpecifier = value
676
- return specifierFormat.encode(reference)
842
+ return urlSpecifierFormat.encode(reference)
677
843
  })
678
844
  }
679
845
  // allow plugin to return a function to bypas default formatting
@@ -698,10 +864,11 @@ const specifierFormat = {
698
864
  },
699
865
  }
700
866
  const formatters = {
701
- js_import_export: { encode: JSON.stringify, decode: JSON.parse },
702
- js_import_meta_url_pattern: { encode: JSON.stringify, decode: JSON.parse },
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 },
703
870
  // https://github.com/webpack-contrib/css-loader/pull/627/files
704
- css_url: {
871
+ "css_url": {
705
872
  encode: (url) => {
706
873
  // If url is already wrapped in quotes, remove them
707
874
  url = formatters.css_url.decode(url)