@jsenv/core 28.1.2 → 28.2.1
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/js/script_type_module_supervisor.js +8 -13
- package/dist/js/supervisor.js +690 -504
- package/dist/main.js +13384 -13228
- package/package.json +6 -6
- package/readme.md +3 -3
- package/src/build/build.js +980 -713
- package/src/build/inject_global_version_mappings.js +5 -20
- package/src/build/start_build_server.js +2 -2
- package/src/dev/start_dev_server.js +6 -3
- package/src/execute/run.js +1 -1
- package/src/omega/compat/runtime_compat.js +9 -6
- package/src/omega/errors.js +3 -0
- package/src/omega/fetched_content_compliance.js +2 -2
- package/src/omega/kitchen.js +191 -146
- package/src/omega/server/file_service.js +104 -71
- package/src/omega/url_graph/url_graph_loader.js +77 -0
- package/src/omega/url_graph/url_info_transformations.js +12 -15
- package/src/omega/url_graph.js +118 -101
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +34 -36
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +3 -2
- package/src/plugins/bundling/js_module/{bundle_js_module.js → bundle_js_modules.js} +51 -14
- package/src/plugins/bundling/jsenv_plugin_bundling.js +2 -2
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +11 -0
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +73 -62
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +77 -89
- package/src/plugins/plugin_controller.js +26 -22
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +1 -0
- package/src/plugins/supervisor/client/script_type_module_supervisor.js +7 -9
- package/src/plugins/supervisor/client/supervisor.js +99 -52
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +2 -4
- package/src/plugins/transpilation/as_js_classic/async-to-promises.js +16 -0
- package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +85 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +48 -190
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +104 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +161 -240
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +91 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +19 -12
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -24
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +82 -52
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +12 -13
- package/src/plugins/url_analysis/html/html_urls.js +91 -34
- package/src/plugins/url_analysis/js/js_urls.js +5 -4
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +1 -0
- package/src/test/execute_plan.js +3 -8
- package/src/test/execute_test_plan.js +1 -1
- package/src/build/inject_service_worker_urls.js +0 -78
- package/src/build/resync_resource_hints.js +0 -112
- package/src/omega/url_graph/url_graph_load.js +0 -74
package/src/omega/url_graph.js
CHANGED
|
@@ -1,32 +1,37 @@
|
|
|
1
1
|
import { urlToRelativeUrl } from "@jsenv/urls"
|
|
2
|
+
|
|
2
3
|
import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
|
|
3
4
|
|
|
4
|
-
export const createUrlGraph = ({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
includeOriginalUrls,
|
|
9
|
-
} = {}) => {
|
|
5
|
+
export const createUrlGraph = () => {
|
|
6
|
+
const createUrlInfoCallbackRef = { current: () => {} }
|
|
7
|
+
const prunedUrlInfosCallbackRef = { current: () => {} }
|
|
8
|
+
|
|
10
9
|
const urlInfoMap = new Map()
|
|
11
10
|
const getUrlInfo = (url) => urlInfoMap.get(url)
|
|
12
11
|
const deleteUrlInfo = (url) => {
|
|
13
12
|
const urlInfo = urlInfoMap.get(url)
|
|
14
13
|
if (urlInfo) {
|
|
15
14
|
urlInfoMap.delete(url)
|
|
15
|
+
urlInfo.dependencies.forEach((dependencyUrl) => {
|
|
16
|
+
getUrlInfo(dependencyUrl).dependents.delete(url)
|
|
17
|
+
})
|
|
16
18
|
if (urlInfo.sourcemapReference) {
|
|
17
19
|
deleteUrlInfo(urlInfo.sourcemapReference.url)
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
|
-
|
|
22
23
|
const reuseOrCreateUrlInfo = (url) => {
|
|
23
24
|
const existingUrlInfo = getUrlInfo(url)
|
|
24
25
|
if (existingUrlInfo) return existingUrlInfo
|
|
25
26
|
const urlInfo = createUrlInfo(url)
|
|
26
27
|
urlInfoMap.set(url, urlInfo)
|
|
27
|
-
|
|
28
|
+
createUrlInfoCallbackRef.current(urlInfo)
|
|
28
29
|
return urlInfo
|
|
29
30
|
}
|
|
31
|
+
const getParentIfInline = (urlInfo) => {
|
|
32
|
+
return urlInfo.isInline ? getUrlInfo(urlInfo.inlineUrlSite.url) : urlInfo
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
const inferReference = (specifier, parentUrl) => {
|
|
31
36
|
const parentUrlInfo = getUrlInfo(parentUrl)
|
|
32
37
|
if (!parentUrlInfo) {
|
|
@@ -39,36 +44,33 @@ export const createUrlGraph = ({
|
|
|
39
44
|
)
|
|
40
45
|
return firstReferenceOnThatUrl
|
|
41
46
|
}
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
const visitDependents = (urlInfo, visitor) => {
|
|
48
|
+
const seen = [urlInfo.url]
|
|
49
|
+
let stopped = false
|
|
50
|
+
const stop = () => {
|
|
51
|
+
stopped = true
|
|
46
52
|
}
|
|
47
|
-
const
|
|
48
|
-
for (const dependentUrl of
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return dependent
|
|
53
|
+
const iterate = (currentUrlInfo) => {
|
|
54
|
+
for (const dependentUrl of currentUrlInfo.dependents) {
|
|
55
|
+
if (seen.includes(dependentUrl)) {
|
|
56
|
+
continue
|
|
52
57
|
}
|
|
53
|
-
|
|
58
|
+
seen.push(dependentUrl)
|
|
59
|
+
const dependentUrlInfo = getUrlInfo(dependentUrl)
|
|
60
|
+
visitor(dependentUrlInfo, stop)
|
|
61
|
+
if (stopped) {
|
|
62
|
+
return dependentUrlInfo
|
|
63
|
+
}
|
|
64
|
+
iterate(dependentUrlInfo)
|
|
54
65
|
}
|
|
55
66
|
return null
|
|
56
67
|
}
|
|
57
|
-
return
|
|
68
|
+
return iterate(urlInfo)
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
const updateReferences = (urlInfo, references) => {
|
|
61
72
|
const setOfDependencyUrls = new Set()
|
|
62
|
-
|
|
63
|
-
// for import assertion "file.css?as_css_module" depends on "file.css"
|
|
64
|
-
// this is enabled only for dev where there is autoreload
|
|
65
|
-
// during build the css file must be considered as not referenced
|
|
66
|
-
// (except if referenced explicitely by something else) so that
|
|
67
|
-
// the css file does not appear in the build directory
|
|
68
|
-
if (includeOriginalUrls && urlInfo.originalUrl !== urlInfo.url) {
|
|
69
|
-
setOfDependencyUrls.add(urlInfo.originalUrl)
|
|
70
|
-
}
|
|
71
|
-
|
|
73
|
+
const setOfImplicitUrls = new Set()
|
|
72
74
|
references.forEach((reference) => {
|
|
73
75
|
if (reference.isResourceHint) {
|
|
74
76
|
// resource hint are a special kind of reference.
|
|
@@ -79,67 +81,83 @@ export const createUrlGraph = ({
|
|
|
79
81
|
// by <link> as dependency and it's fine
|
|
80
82
|
return
|
|
81
83
|
}
|
|
82
|
-
|
|
84
|
+
const dependencyUrl = reference.url
|
|
85
|
+
setOfDependencyUrls.add(dependencyUrl)
|
|
86
|
+
// an implicit reference do not appear in the file but a non-explicited file have an impact on it
|
|
87
|
+
// (package.json on import resolution for instance)
|
|
88
|
+
// in that case:
|
|
89
|
+
// - file depends on the implicit file (it must autoreload if package.json is modified)
|
|
90
|
+
// - cache validity for the file depends on the implicit file (it must be re-cooked in package.json is modified)
|
|
91
|
+
if (reference.isImplicit) {
|
|
92
|
+
setOfImplicitUrls.add(dependencyUrl)
|
|
93
|
+
}
|
|
83
94
|
})
|
|
84
|
-
const urlsToRemove = Array.from(urlInfo.dependencies).filter(
|
|
85
|
-
(dep) => !setOfDependencyUrls.has(dep),
|
|
86
|
-
)
|
|
87
|
-
pruneDependencies(urlInfo, urlsToRemove)
|
|
88
|
-
urlInfo.references = references
|
|
89
95
|
setOfDependencyUrls.forEach((dependencyUrl) => {
|
|
90
|
-
const dependencyUrlInfo = reuseOrCreateUrlInfo(dependencyUrl)
|
|
91
96
|
urlInfo.dependencies.add(dependencyUrl)
|
|
97
|
+
const dependencyUrlInfo = reuseOrCreateUrlInfo(dependencyUrl)
|
|
92
98
|
dependencyUrlInfo.dependents.add(urlInfo.url)
|
|
93
99
|
})
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
setOfImplicitUrls.forEach((implicitUrl) => {
|
|
101
|
+
urlInfo.implicitUrls.add(implicitUrl)
|
|
102
|
+
if (urlInfo.isInline) {
|
|
103
|
+
const parentUrlInfo = getUrlInfo(urlInfo.inlineUrlSite.url)
|
|
104
|
+
parentUrlInfo.implicitUrls.add(implicitUrl)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
97
107
|
const prunedUrlInfos = []
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
prunedUrlInfos.push(dependencyUrlInfo)
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
removeDependencies(firstUrlInfo, urlsToRemove)
|
|
116
|
-
if (prunedUrlInfos.length === 0) {
|
|
117
|
-
return
|
|
108
|
+
const pruneDependency = (urlInfo, urlToClean) => {
|
|
109
|
+
urlInfo.dependencies.delete(urlToClean)
|
|
110
|
+
const dependencyUrlInfo = getUrlInfo(urlToClean)
|
|
111
|
+
if (!dependencyUrlInfo) {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
dependencyUrlInfo.dependents.delete(urlInfo.url)
|
|
115
|
+
if (dependencyUrlInfo.dependents.size === 0) {
|
|
116
|
+
dependencyUrlInfo.dependencies.forEach((dependencyUrl) => {
|
|
117
|
+
pruneDependency(dependencyUrlInfo, dependencyUrl)
|
|
118
|
+
})
|
|
119
|
+
prunedUrlInfos.push(dependencyUrlInfo)
|
|
120
|
+
}
|
|
118
121
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// should we always delete?
|
|
123
|
-
deleteUrlInfo(prunedUrlInfo.url)
|
|
122
|
+
urlInfo.dependencies.forEach((dependencyUrl) => {
|
|
123
|
+
if (!setOfDependencyUrls.has(dependencyUrl)) {
|
|
124
|
+
pruneDependency(urlInfo, dependencyUrl)
|
|
124
125
|
}
|
|
125
126
|
})
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
if (prunedUrlInfos.length) {
|
|
128
|
+
prunedUrlInfos.forEach((prunedUrlInfo) => {
|
|
129
|
+
prunedUrlInfo.modifiedTimestamp = Date.now()
|
|
130
|
+
if (prunedUrlInfo.isInline) {
|
|
131
|
+
// should we always delete?
|
|
132
|
+
deleteUrlInfo(prunedUrlInfo.url)
|
|
133
|
+
}
|
|
132
134
|
})
|
|
135
|
+
prunedUrlInfosCallbackRef.current(prunedUrlInfos, urlInfo)
|
|
133
136
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
urlInfo.implicitUrls.forEach((implicitUrl) => {
|
|
138
|
+
if (!setOfDependencyUrls.has(implicitUrl)) {
|
|
139
|
+
let implicitUrlComesFromInlineContent = false
|
|
140
|
+
for (const dependencyUrl of urlInfo.dependencies) {
|
|
141
|
+
const dependencyUrlInfo = getUrlInfo(dependencyUrl)
|
|
142
|
+
if (
|
|
143
|
+
dependencyUrlInfo.isInline &&
|
|
144
|
+
dependencyUrlInfo.implicitUrls.has(implicitUrl)
|
|
145
|
+
) {
|
|
146
|
+
implicitUrlComesFromInlineContent = true
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!implicitUrlComesFromInlineContent) {
|
|
151
|
+
urlInfo.implicitUrls.delete(implicitUrl)
|
|
152
|
+
}
|
|
153
|
+
if (urlInfo.isInline) {
|
|
154
|
+
const parentUrlInfo = getUrlInfo(urlInfo.inlineUrlSite.url)
|
|
155
|
+
parentUrlInfo.implicitUrls.delete(implicitUrl)
|
|
156
|
+
}
|
|
141
157
|
}
|
|
142
158
|
})
|
|
159
|
+
urlInfo.references = references
|
|
160
|
+
return urlInfo
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
const considerModified = (urlInfo, modifiedTimestamp = Date.now()) => {
|
|
@@ -150,6 +168,7 @@ export const createUrlGraph = ({
|
|
|
150
168
|
}
|
|
151
169
|
seen.push(urlInfo.url)
|
|
152
170
|
urlInfo.modifiedTimestamp = modifiedTimestamp
|
|
171
|
+
urlInfo.originalContentEtag = undefined
|
|
153
172
|
urlInfo.contentEtag = undefined
|
|
154
173
|
urlInfo.dependents.forEach((dependentUrl) => {
|
|
155
174
|
const dependentUrlInfo = getUrlInfo(dependentUrl)
|
|
@@ -168,30 +187,20 @@ export const createUrlGraph = ({
|
|
|
168
187
|
iterate(urlInfo)
|
|
169
188
|
}
|
|
170
189
|
|
|
171
|
-
const getRelatedUrlInfos = (url) => {
|
|
172
|
-
const urlInfosUntilNotInline = []
|
|
173
|
-
const parentUrlInfo = getUrlInfo(url)
|
|
174
|
-
if (parentUrlInfo) {
|
|
175
|
-
urlInfosUntilNotInline.push(parentUrlInfo)
|
|
176
|
-
if (parentUrlInfo.inlineUrlSite) {
|
|
177
|
-
urlInfosUntilNotInline.push(
|
|
178
|
-
...getRelatedUrlInfos(parentUrlInfo.inlineUrlSite.url),
|
|
179
|
-
)
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return urlInfosUntilNotInline
|
|
183
|
-
}
|
|
184
|
-
|
|
185
190
|
return {
|
|
191
|
+
createUrlInfoCallbackRef,
|
|
192
|
+
prunedUrlInfosCallbackRef,
|
|
193
|
+
|
|
186
194
|
urlInfoMap,
|
|
187
195
|
reuseOrCreateUrlInfo,
|
|
188
196
|
getUrlInfo,
|
|
189
197
|
deleteUrlInfo,
|
|
198
|
+
getParentIfInline,
|
|
199
|
+
|
|
190
200
|
inferReference,
|
|
191
|
-
findDependent,
|
|
192
201
|
updateReferences,
|
|
193
202
|
considerModified,
|
|
194
|
-
|
|
203
|
+
visitDependents,
|
|
195
204
|
|
|
196
205
|
toObject: () => {
|
|
197
206
|
const data = {}
|
|
@@ -217,26 +226,25 @@ export const createUrlGraph = ({
|
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
const createUrlInfo = (url) => {
|
|
220
|
-
|
|
229
|
+
const urlInfo = {
|
|
221
230
|
error: null,
|
|
222
231
|
modifiedTimestamp: 0,
|
|
232
|
+
originalContentEtag: null,
|
|
223
233
|
contentEtag: null,
|
|
224
|
-
|
|
225
|
-
isValid,
|
|
234
|
+
isWatched: false,
|
|
235
|
+
isValid: () => false,
|
|
226
236
|
data: {}, // plugins can put whatever they want here
|
|
227
237
|
references: [],
|
|
228
238
|
dependencies: new Set(),
|
|
229
239
|
dependents: new Set(),
|
|
240
|
+
implicitUrls: new Set(),
|
|
230
241
|
type: undefined, // "html", "css", "js_classic", "js_module", "importmap", "json", "webmanifest", ...
|
|
231
242
|
subtype: undefined, // "worker", "service_worker", "shared_worker" for js, otherwise undefined
|
|
232
243
|
contentType: "", // "text/html", "text/css", "text/javascript", "application/json", ...
|
|
233
244
|
url,
|
|
234
245
|
originalUrl: undefined,
|
|
235
|
-
generatedUrl: null,
|
|
236
246
|
filename: "",
|
|
237
247
|
isEntryPoint: false,
|
|
238
|
-
isInline: false,
|
|
239
|
-
inlineUrlSite: null,
|
|
240
248
|
shouldHandle: undefined,
|
|
241
249
|
originalContent: undefined,
|
|
242
250
|
content: undefined,
|
|
@@ -244,9 +252,18 @@ const createUrlInfo = (url) => {
|
|
|
244
252
|
sourcemap: null,
|
|
245
253
|
sourcemapReference: null,
|
|
246
254
|
sourcemapIsWrong: false,
|
|
255
|
+
|
|
256
|
+
generatedUrl: null,
|
|
257
|
+
sourcemapGeneratedUrl: null,
|
|
258
|
+
injected: false,
|
|
259
|
+
|
|
260
|
+
isInline: false,
|
|
261
|
+
inlineUrlSite: null,
|
|
262
|
+
jsQuote: null, // maybe move to inlineUrlSite?
|
|
263
|
+
|
|
247
264
|
timing: {},
|
|
248
265
|
headers: {},
|
|
249
266
|
}
|
|
267
|
+
// Object.preventExtensions(urlInfo) // useful to ensure all properties are declared here
|
|
268
|
+
return urlInfo
|
|
250
269
|
}
|
|
251
|
-
|
|
252
|
-
const isValid = () => false
|
|
@@ -19,6 +19,7 @@ export const jsenvPluginAutoreloadClient = () => {
|
|
|
19
19
|
const htmlAst = parseHtmlString(htmlUrlInfo.content)
|
|
20
20
|
const [autoreloadClientReference] = context.referenceUtils.inject({
|
|
21
21
|
type: "script_src",
|
|
22
|
+
subtype: "js_module",
|
|
22
23
|
expectedType: "js_module",
|
|
23
24
|
specifier: autoreloadClientFileUrl,
|
|
24
25
|
})
|
|
@@ -134,48 +134,46 @@ export const jsenvPluginAutoreloadServer = ({
|
|
|
134
134
|
})
|
|
135
135
|
}
|
|
136
136
|
})
|
|
137
|
-
clientFilesPruneCallbackList.push(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
clientFilesPruneCallbackList.push((prunedUrlInfos, firstUrlInfo) => {
|
|
138
|
+
const mainHotUpdate = propagateUpdate(firstUrlInfo)
|
|
139
|
+
const cause = `following files are no longer referenced: ${prunedUrlInfos.map(
|
|
140
|
+
(prunedUrlInfo) => formatUrlForClient(prunedUrlInfo.url),
|
|
141
|
+
)}`
|
|
142
|
+
// now check if we can hot update the main resource
|
|
143
|
+
// then if we can hot update all dependencies
|
|
144
|
+
if (mainHotUpdate.declined) {
|
|
145
|
+
notifyDeclined({
|
|
146
|
+
cause,
|
|
147
|
+
reason: mainHotUpdate.reason,
|
|
148
|
+
declinedBy: mainHotUpdate.declinedBy,
|
|
149
|
+
})
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
// main can hot update
|
|
153
|
+
let i = 0
|
|
154
|
+
const instructions = []
|
|
155
|
+
while (i < prunedUrlInfos.length) {
|
|
156
|
+
const prunedUrlInfo = prunedUrlInfos[i++]
|
|
157
|
+
if (prunedUrlInfo.data.hotDecline) {
|
|
146
158
|
notifyDeclined({
|
|
147
159
|
cause,
|
|
148
|
-
reason:
|
|
149
|
-
declinedBy:
|
|
160
|
+
reason: `a pruned file declines hot reload`,
|
|
161
|
+
declinedBy: formatUrlForClient(prunedUrlInfo.url),
|
|
150
162
|
})
|
|
151
163
|
return
|
|
152
164
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const prunedUrlInfo = prunedUrlInfos[i++]
|
|
158
|
-
if (prunedUrlInfo.data.hotDecline) {
|
|
159
|
-
notifyDeclined({
|
|
160
|
-
cause,
|
|
161
|
-
reason: `a pruned file declines hot reload`,
|
|
162
|
-
declinedBy: formatUrlForClient(prunedUrlInfo.url),
|
|
163
|
-
})
|
|
164
|
-
return
|
|
165
|
-
}
|
|
166
|
-
instructions.push({
|
|
167
|
-
type: "prune",
|
|
168
|
-
boundary: formatUrlForClient(prunedUrlInfo.url),
|
|
169
|
-
acceptedBy: formatUrlForClient(firstUrlInfo.url),
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
notifyAccepted({
|
|
173
|
-
cause,
|
|
174
|
-
reason: mainHotUpdate.reason,
|
|
175
|
-
instructions,
|
|
165
|
+
instructions.push({
|
|
166
|
+
type: "prune",
|
|
167
|
+
boundary: formatUrlForClient(prunedUrlInfo.url),
|
|
168
|
+
acceptedBy: formatUrlForClient(firstUrlInfo.url),
|
|
176
169
|
})
|
|
177
|
-
}
|
|
178
|
-
|
|
170
|
+
}
|
|
171
|
+
notifyAccepted({
|
|
172
|
+
cause,
|
|
173
|
+
reason: mainHotUpdate.reason,
|
|
174
|
+
instructions,
|
|
175
|
+
})
|
|
176
|
+
})
|
|
179
177
|
},
|
|
180
178
|
},
|
|
181
179
|
serve: (request, { rootDirectoryUrl, urlGraph }) => {
|
|
@@ -3,12 +3,13 @@ export const jsenvPluginHmr = () => {
|
|
|
3
3
|
name: "jsenv:hmr",
|
|
4
4
|
appliesDuring: "dev",
|
|
5
5
|
redirectUrl: (reference) => {
|
|
6
|
-
|
|
7
|
-
if (!urlObject.searchParams.has("hmr")) {
|
|
6
|
+
if (!reference.searchParams.has("hmr")) {
|
|
8
7
|
reference.data.hmr = false
|
|
9
8
|
return null
|
|
10
9
|
}
|
|
10
|
+
|
|
11
11
|
reference.data.hmr = true
|
|
12
|
+
const urlObject = new URL(reference.url)
|
|
12
13
|
// "hmr" search param goal is to mark url as enabling hmr:
|
|
13
14
|
// this goal is achieved when we reach this part of the code
|
|
14
15
|
// We get rid of this params so that urlGraph and other parts of the code
|
|
@@ -21,7 +21,7 @@ const regeneratorRuntimeClientFileUrl = new URL(
|
|
|
21
21
|
import.meta.url,
|
|
22
22
|
).href
|
|
23
23
|
|
|
24
|
-
export const
|
|
24
|
+
export const bundleJsModules = async ({
|
|
25
25
|
jsModuleUrlInfos,
|
|
26
26
|
context,
|
|
27
27
|
options,
|
|
@@ -35,7 +35,11 @@ export const bundleJsModule = async ({
|
|
|
35
35
|
runtimeCompat,
|
|
36
36
|
sourcemaps,
|
|
37
37
|
} = context
|
|
38
|
-
const {
|
|
38
|
+
const {
|
|
39
|
+
babelHelpersChunk = true,
|
|
40
|
+
include,
|
|
41
|
+
preserveDynamicImport = false,
|
|
42
|
+
} = options
|
|
39
43
|
const { jsModuleBundleUrlInfos } = await buildWithRollup({
|
|
40
44
|
signal,
|
|
41
45
|
logger,
|
|
@@ -49,6 +53,7 @@ export const bundleJsModule = async ({
|
|
|
49
53
|
|
|
50
54
|
include,
|
|
51
55
|
babelHelpersChunk,
|
|
56
|
+
preserveDynamicImport,
|
|
52
57
|
})
|
|
53
58
|
return jsModuleBundleUrlInfos
|
|
54
59
|
}
|
|
@@ -63,12 +68,18 @@ const rollupPluginJsenv = ({
|
|
|
63
68
|
|
|
64
69
|
include,
|
|
65
70
|
babelHelpersChunk,
|
|
71
|
+
preserveDynamicImport,
|
|
66
72
|
|
|
67
73
|
resultRef,
|
|
68
74
|
}) => {
|
|
69
75
|
let _rollupEmitFile = () => {
|
|
70
76
|
throw new Error("not implemented")
|
|
71
77
|
}
|
|
78
|
+
const format = jsModuleUrlInfos.some((jsModuleUrlInfo) =>
|
|
79
|
+
jsModuleUrlInfo.filename.endsWith(".cjs"),
|
|
80
|
+
)
|
|
81
|
+
? "cjs"
|
|
82
|
+
: "esm"
|
|
72
83
|
const emitChunk = (chunk) => {
|
|
73
84
|
return _rollupEmitFile({
|
|
74
85
|
type: "chunk",
|
|
@@ -118,7 +129,16 @@ const rollupPluginJsenv = ({
|
|
|
118
129
|
const rollupFileInfo = rollupResult[fileName]
|
|
119
130
|
// there is 3 types of file: "placeholder", "asset", "chunk"
|
|
120
131
|
if (rollupFileInfo.type === "chunk") {
|
|
132
|
+
let url
|
|
133
|
+
if (rollupFileInfo.facadeModuleId) {
|
|
134
|
+
url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
|
|
135
|
+
} else {
|
|
136
|
+
url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
|
|
137
|
+
}
|
|
121
138
|
const jsModuleBundleUrlInfo = {
|
|
139
|
+
url,
|
|
140
|
+
originalUrl: url,
|
|
141
|
+
type: format === "esm" ? "js_module" : "common_js",
|
|
122
142
|
data: {
|
|
123
143
|
generatedBy: "rollup",
|
|
124
144
|
bundleRelativeUrl: rollupFileInfo.fileName,
|
|
@@ -126,16 +146,13 @@ const rollupPluginJsenv = ({
|
|
|
126
146
|
rollupFileInfo.imports.length > 0 ||
|
|
127
147
|
rollupFileInfo.dynamicImports.length > 0,
|
|
128
148
|
},
|
|
149
|
+
sourceUrls: Object.keys(rollupFileInfo.modules).map((id) =>
|
|
150
|
+
fileUrlConverter.asFileUrl(id),
|
|
151
|
+
),
|
|
129
152
|
contentType: "text/javascript",
|
|
130
153
|
content: rollupFileInfo.code,
|
|
131
154
|
sourcemap: rollupFileInfo.map,
|
|
132
155
|
}
|
|
133
|
-
let url
|
|
134
|
-
if (rollupFileInfo.facadeModuleId) {
|
|
135
|
-
url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
|
|
136
|
-
} else {
|
|
137
|
-
url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
|
|
138
|
-
}
|
|
139
156
|
jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
|
|
140
157
|
}
|
|
141
158
|
})
|
|
@@ -146,11 +163,7 @@ const rollupPluginJsenv = ({
|
|
|
146
163
|
outputOptions: (outputOptions) => {
|
|
147
164
|
// const sourcemapFile = buildDirectoryUrl
|
|
148
165
|
Object.assign(outputOptions, {
|
|
149
|
-
format
|
|
150
|
-
jsModuleUrlInfo.filename.endsWith(".cjs"),
|
|
151
|
-
)
|
|
152
|
-
? "cjs"
|
|
153
|
-
: "esm",
|
|
166
|
+
format,
|
|
154
167
|
dir: fileUrlConverter.asFilePath(buildDirectoryUrl),
|
|
155
168
|
sourcemap: sourcemaps === "file" || sourcemaps === "inline",
|
|
156
169
|
// sourcemapFile,
|
|
@@ -210,11 +223,33 @@ const rollupPluginJsenv = ({
|
|
|
210
223
|
// },
|
|
211
224
|
})
|
|
212
225
|
},
|
|
226
|
+
// https://rollupjs.org/guide/en/#resolvedynamicimport
|
|
227
|
+
resolveDynamicImport: (specifier, importer) => {
|
|
228
|
+
if (preserveDynamicImport) {
|
|
229
|
+
let urlObject
|
|
230
|
+
if (specifier[0] === "/") {
|
|
231
|
+
urlObject = new URL(specifier.slice(1), rootDirectoryUrl)
|
|
232
|
+
} else {
|
|
233
|
+
if (isFileSystemPath(importer)) {
|
|
234
|
+
importer = fileUrlConverter.asFileUrl(importer)
|
|
235
|
+
}
|
|
236
|
+
urlObject = new URL(specifier, importer)
|
|
237
|
+
}
|
|
238
|
+
urlObject.searchParams.set("as_js_classic_library", "")
|
|
239
|
+
return { external: true, id: urlObject.href }
|
|
240
|
+
}
|
|
241
|
+
return null
|
|
242
|
+
},
|
|
213
243
|
resolveId: (specifier, importer = rootDirectoryUrl) => {
|
|
214
244
|
if (isFileSystemPath(importer)) {
|
|
215
245
|
importer = fileUrlConverter.asFileUrl(importer)
|
|
216
246
|
}
|
|
217
|
-
|
|
247
|
+
let url
|
|
248
|
+
if (specifier[0] === "/") {
|
|
249
|
+
url = new URL(specifier.slice(1), rootDirectoryUrl).href
|
|
250
|
+
} else {
|
|
251
|
+
url = new URL(specifier, importer).href
|
|
252
|
+
}
|
|
218
253
|
const existingImporter = urlImporters[url]
|
|
219
254
|
if (!existingImporter) {
|
|
220
255
|
urlImporters[url] = importer
|
|
@@ -262,6 +297,7 @@ const buildWithRollup = async ({
|
|
|
262
297
|
|
|
263
298
|
include,
|
|
264
299
|
babelHelpersChunk,
|
|
300
|
+
preserveDynamicImport,
|
|
265
301
|
}) => {
|
|
266
302
|
const resultRef = { current: null }
|
|
267
303
|
try {
|
|
@@ -279,6 +315,7 @@ const buildWithRollup = async ({
|
|
|
279
315
|
sourcemaps,
|
|
280
316
|
include,
|
|
281
317
|
babelHelpersChunk,
|
|
318
|
+
preserveDynamicImport,
|
|
282
319
|
resultRef,
|
|
283
320
|
}),
|
|
284
321
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bundleCss } from "./css/bundle_css.js"
|
|
2
2
|
import { bundleJsClassicWorkers } from "./js_classic_workers/bundle_js_classic_workers.js"
|
|
3
|
-
import {
|
|
3
|
+
import { bundleJsModules } from "./js_module/bundle_js_modules.js"
|
|
4
4
|
|
|
5
5
|
export const jsenvPluginBundling = (bundling) => {
|
|
6
6
|
if (typeof bundling === "boolean") {
|
|
@@ -40,7 +40,7 @@ export const jsenvPluginBundling = (bundling) => {
|
|
|
40
40
|
: undefined,
|
|
41
41
|
js_module: bundling.js_module
|
|
42
42
|
? (jsModuleUrlInfos, context) => {
|
|
43
|
-
return
|
|
43
|
+
return bundleJsModules({
|
|
44
44
|
jsModuleUrlInfos,
|
|
45
45
|
context,
|
|
46
46
|
options: bundling.js_module,
|
|
@@ -25,6 +25,17 @@ export const jsenvPluginImportMetaHot = () => {
|
|
|
25
25
|
htmlUrlInfo.data.hotAcceptSelf = false
|
|
26
26
|
htmlUrlInfo.data.hotAcceptDependencies = hotReferences.map(
|
|
27
27
|
({ type, specifier }) => {
|
|
28
|
+
const existingReference = context.referenceUtils.find(
|
|
29
|
+
(existingReference) => {
|
|
30
|
+
return (
|
|
31
|
+
existingReference.type === type &&
|
|
32
|
+
existingReference.specifier === specifier
|
|
33
|
+
)
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
if (existingReference) {
|
|
37
|
+
return existingReference.url
|
|
38
|
+
}
|
|
28
39
|
const [reference] = context.referenceUtils.found({
|
|
29
40
|
type,
|
|
30
41
|
specifier,
|