@jsenv/core 27.3.2 → 27.4.0
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/README.md +16 -4
- package/dist/controllable_child_process.mjs +1 -0
- package/dist/controllable_worker_thread.mjs +1 -0
- package/dist/js/event_source_client.js +45 -24
- package/dist/js/execute_using_dynamic_import.js +5 -3
- package/dist/js/html_supervisor_installer.js +368 -139
- package/dist/main.js +668 -471
- package/package.json +5 -6
- package/src/build/build.js +6 -4
- package/src/build/graph_utils.js +14 -11
- package/src/execute/run.js +29 -28
- package/src/execute/runtimes/browsers/from_playwright.js +90 -92
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +8 -2
- package/src/execute/runtimes/node/node_child_process.js +2 -0
- package/src/execute/runtimes/node/node_worker_thread.js +11 -6
- package/src/helpers/event_source/event_source.js +38 -17
- package/src/omega/errors.js +41 -9
- package/src/omega/kitchen.js +35 -19
- package/src/omega/omega_server.js +54 -1
- package/src/omega/server/file_service.js +30 -3
- package/src/omega/url_graph/url_graph_report.js +2 -4
- package/src/omega/url_graph.js +29 -16
- package/src/plugins/autoreload/dev_sse/client/event_source_client.js +8 -8
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +160 -172
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
- package/src/plugins/bundling/js_module/bundle_js_module.js +0 -1
- package/src/plugins/html_supervisor/client/error_in_document.js +268 -121
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +47 -5
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +37 -12
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +1 -2
- package/src/plugins/plugins.js +0 -2
- package/src/plugins/url_analysis/js/js_urls.js +0 -9
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +3 -1
- package/src/test/coverage/report_to_coverage.js +16 -11
- package/src/test/execute_plan.js +3 -2
- package/src/test/execute_test_plan.js +3 -1
- package/src/test/logs_file_execution.js +60 -27
- package/src/test/logs_file_execution.test.mjs +41 -0
|
@@ -1,184 +1,180 @@
|
|
|
1
1
|
import { urlToRelativeUrl } from "@jsenv/urls"
|
|
2
|
-
import { createCallbackList } from "@jsenv/abort"
|
|
3
|
-
|
|
4
|
-
import { createSSEService } from "@jsenv/core/src/helpers/event_source/sse_service.js"
|
|
5
2
|
|
|
6
3
|
export const jsenvPluginDevSSEServer = ({
|
|
7
|
-
rootDirectoryUrl,
|
|
8
|
-
urlGraph,
|
|
9
4
|
clientFileChangeCallbackList,
|
|
10
5
|
clientFilesPruneCallbackList,
|
|
11
6
|
}) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
data: JSON.stringify({
|
|
30
|
-
cause,
|
|
31
|
-
type: "hot",
|
|
32
|
-
typeReason: reason,
|
|
33
|
-
hotInstructions: instructions,
|
|
34
|
-
}),
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
const propagateUpdate = (firstUrlInfo) => {
|
|
38
|
-
const urlInfos = urlGraph.urlInfos
|
|
39
|
-
const iterate = (urlInfo, trace) => {
|
|
40
|
-
if (urlInfo.data.hotAcceptSelf) {
|
|
41
|
-
return {
|
|
42
|
-
accepted: true,
|
|
43
|
-
reason:
|
|
44
|
-
urlInfo === firstUrlInfo
|
|
45
|
-
? `file accepts hot reload`
|
|
46
|
-
: `a dependent file accepts hot reload`,
|
|
47
|
-
instructions: [
|
|
48
|
-
{
|
|
49
|
-
type: urlInfo.type,
|
|
50
|
-
boundary: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
51
|
-
acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
}
|
|
7
|
+
return {
|
|
8
|
+
name: "jsenv:sse_server",
|
|
9
|
+
appliesDuring: { dev: true },
|
|
10
|
+
registerServerEvents: (
|
|
11
|
+
{ sendServerEvent },
|
|
12
|
+
{ rootDirectoryUrl, urlGraph },
|
|
13
|
+
) => {
|
|
14
|
+
const notifyDeclined = ({ cause, reason, declinedBy }) => {
|
|
15
|
+
sendServerEvent({
|
|
16
|
+
type: "reload",
|
|
17
|
+
data: {
|
|
18
|
+
cause,
|
|
19
|
+
type: "full",
|
|
20
|
+
typeReason: reason,
|
|
21
|
+
declinedBy,
|
|
22
|
+
},
|
|
23
|
+
})
|
|
55
24
|
}
|
|
56
|
-
const {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
25
|
+
const notifyAccepted = ({ cause, reason, instructions }) => {
|
|
26
|
+
sendServerEvent({
|
|
27
|
+
type: "reload",
|
|
28
|
+
data: {
|
|
29
|
+
cause,
|
|
30
|
+
type: "hot",
|
|
31
|
+
typeReason: reason,
|
|
32
|
+
hotInstructions: instructions,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
const propagateUpdate = (firstUrlInfo) => {
|
|
37
|
+
const iterate = (urlInfo, seen) => {
|
|
38
|
+
if (urlInfo.data.hotAcceptSelf) {
|
|
39
|
+
return {
|
|
40
|
+
accepted: true,
|
|
41
|
+
reason:
|
|
42
|
+
urlInfo === firstUrlInfo
|
|
43
|
+
? `file accepts hot reload`
|
|
44
|
+
: `a dependent file accepts hot reload`,
|
|
45
|
+
instructions: [
|
|
46
|
+
{
|
|
47
|
+
type: urlInfo.type,
|
|
48
|
+
boundary: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
49
|
+
acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const { dependents } = urlInfo
|
|
55
|
+
const instructions = []
|
|
56
|
+
for (const dependentUrl of dependents) {
|
|
57
|
+
const dependentUrlInfo = urlGraph.getUrlInfo(dependentUrl)
|
|
58
|
+
if (dependentUrlInfo.data.hotDecline) {
|
|
59
|
+
return {
|
|
60
|
+
declined: true,
|
|
61
|
+
reason: `a dependent file declines hot reload`,
|
|
62
|
+
declinedBy: dependentUrl,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const { hotAcceptDependencies = [] } = dependentUrlInfo.data
|
|
66
|
+
if (hotAcceptDependencies.includes(urlInfo.url)) {
|
|
67
|
+
instructions.push({
|
|
68
|
+
type: dependentUrlInfo.type,
|
|
69
|
+
boundary: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
|
|
70
|
+
acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
71
|
+
})
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
if (seen.includes(dependentUrl)) {
|
|
75
|
+
return {
|
|
76
|
+
declined: true,
|
|
77
|
+
reason: "circular dependency",
|
|
78
|
+
declinedBy: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const dependentPropagationResult = iterate(dependentUrlInfo, [
|
|
82
|
+
...seen,
|
|
83
|
+
dependentUrl,
|
|
84
|
+
])
|
|
85
|
+
if (dependentPropagationResult.accepted) {
|
|
86
|
+
instructions.push(...dependentPropagationResult.instructions)
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
if (
|
|
90
|
+
// declined explicitely by an other file, it must decline the whole update
|
|
91
|
+
dependentPropagationResult.declinedBy
|
|
92
|
+
) {
|
|
93
|
+
return dependentPropagationResult
|
|
94
|
+
}
|
|
95
|
+
// declined by absence of boundary, we can keep searching
|
|
96
|
+
continue
|
|
97
|
+
}
|
|
98
|
+
if (instructions.length === 0) {
|
|
99
|
+
return {
|
|
100
|
+
declined: true,
|
|
101
|
+
reason: `there is no file accepting hot reload while propagating update`,
|
|
102
|
+
}
|
|
65
103
|
}
|
|
66
|
-
}
|
|
67
|
-
const { hotAcceptDependencies = [] } = dependentUrlInfo.data
|
|
68
|
-
if (hotAcceptDependencies.includes(urlInfo.url)) {
|
|
69
|
-
instructions.push({
|
|
70
|
-
type: dependentUrlInfo.type,
|
|
71
|
-
boundary: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
|
|
72
|
-
acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
|
|
73
|
-
})
|
|
74
|
-
continue
|
|
75
|
-
}
|
|
76
|
-
if (trace.includes(dependentUrl)) {
|
|
77
104
|
return {
|
|
78
|
-
|
|
79
|
-
reason:
|
|
80
|
-
|
|
105
|
+
accepted: true,
|
|
106
|
+
reason: `${instructions.length} dependent file(s) accepts hot reload`,
|
|
107
|
+
instructions,
|
|
81
108
|
}
|
|
82
109
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
dependentUrl,
|
|
86
|
-
])
|
|
87
|
-
if (dependentPropagationResult.accepted) {
|
|
88
|
-
instructions.push(...dependentPropagationResult.instructions)
|
|
89
|
-
continue
|
|
90
|
-
}
|
|
91
|
-
if (
|
|
92
|
-
// declined explicitely by an other file, it must decline the whole update
|
|
93
|
-
dependentPropagationResult.declinedBy
|
|
94
|
-
) {
|
|
95
|
-
return dependentPropagationResult
|
|
96
|
-
}
|
|
97
|
-
// declined by absence of boundary, we can keep searching
|
|
98
|
-
continue
|
|
110
|
+
const seen = []
|
|
111
|
+
return iterate(firstUrlInfo, seen)
|
|
99
112
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
113
|
+
clientFileChangeCallbackList.push(({ url, event }) => {
|
|
114
|
+
const urlInfo = urlGraph.getUrlInfo(url)
|
|
115
|
+
// file not part of dependency graph
|
|
116
|
+
if (!urlInfo) {
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
|
|
120
|
+
const hotUpdate = propagateUpdate(urlInfo)
|
|
121
|
+
if (hotUpdate.declined) {
|
|
122
|
+
notifyDeclined({
|
|
123
|
+
cause: `${relativeUrl} ${event}`,
|
|
124
|
+
reason: hotUpdate.reason,
|
|
125
|
+
declinedBy: hotUpdate.declinedBy,
|
|
126
|
+
})
|
|
127
|
+
} else {
|
|
128
|
+
notifyAccepted({
|
|
129
|
+
cause: `${relativeUrl} ${event}`,
|
|
130
|
+
reason: hotUpdate.reason,
|
|
131
|
+
instructions: hotUpdate.instructions,
|
|
132
|
+
})
|
|
104
133
|
}
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
accepted: true,
|
|
108
|
-
reason: `${instructions.length} dependent file(s) accepts hot reload`,
|
|
109
|
-
instructions,
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const trace = []
|
|
113
|
-
return iterate(firstUrlInfo, trace)
|
|
114
|
-
}
|
|
115
|
-
clientFileChangeCallbackList.push(({ url, event }) => {
|
|
116
|
-
const urlInfo = urlGraph.getUrlInfo(url)
|
|
117
|
-
// file not part of dependency graph
|
|
118
|
-
if (!urlInfo) {
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
|
|
122
|
-
const hotUpdate = propagateUpdate(urlInfo)
|
|
123
|
-
if (hotUpdate.declined) {
|
|
124
|
-
notifyDeclined({
|
|
125
|
-
cause: `${relativeUrl} ${event}`,
|
|
126
|
-
reason: hotUpdate.reason,
|
|
127
|
-
declinedBy: hotUpdate.declinedBy,
|
|
128
|
-
})
|
|
129
|
-
} else {
|
|
130
|
-
notifyAccepted({
|
|
131
|
-
cause: `${relativeUrl} ${event}`,
|
|
132
|
-
reason: hotUpdate.reason,
|
|
133
|
-
instructions: hotUpdate.instructions,
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
})
|
|
137
|
-
clientFilesPruneCallbackList.push(({ prunedUrlInfos, firstUrlInfo }) => {
|
|
138
|
-
const mainHotUpdate = propagateUpdate(firstUrlInfo)
|
|
139
|
-
const cause = `following files are no longer referenced: ${prunedUrlInfos.map(
|
|
140
|
-
(prunedUrlInfo) => urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
|
|
141
|
-
)}`
|
|
142
|
-
// now check if we can hot update the main ressource
|
|
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
134
|
})
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
135
|
+
clientFilesPruneCallbackList.push(({ prunedUrlInfos, firstUrlInfo }) => {
|
|
136
|
+
const mainHotUpdate = propagateUpdate(firstUrlInfo)
|
|
137
|
+
const cause = `following files are no longer referenced: ${prunedUrlInfos.map(
|
|
138
|
+
(prunedUrlInfo) =>
|
|
139
|
+
urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
|
|
140
|
+
)}`
|
|
141
|
+
// now check if we can hot update the main ressource
|
|
142
|
+
// then if we can hot update all dependencies
|
|
143
|
+
if (mainHotUpdate.declined) {
|
|
144
|
+
notifyDeclined({
|
|
145
|
+
cause,
|
|
146
|
+
reason: mainHotUpdate.reason,
|
|
147
|
+
declinedBy: mainHotUpdate.declinedBy,
|
|
148
|
+
})
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
// main can hot update
|
|
152
|
+
let i = 0
|
|
153
|
+
const instructions = []
|
|
154
|
+
while (i < prunedUrlInfos.length) {
|
|
155
|
+
const prunedUrlInfo = prunedUrlInfos[i++]
|
|
156
|
+
if (prunedUrlInfo.data.hotDecline) {
|
|
157
|
+
notifyDeclined({
|
|
158
|
+
cause,
|
|
159
|
+
reason: `a pruned file declines hot reload`,
|
|
160
|
+
declinedBy: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
|
|
161
|
+
})
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
instructions.push({
|
|
165
|
+
type: "prune",
|
|
166
|
+
boundary: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
|
|
167
|
+
acceptedBy: urlToRelativeUrl(firstUrlInfo.url, rootDirectoryUrl),
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
notifyAccepted({
|
|
159
171
|
cause,
|
|
160
|
-
reason:
|
|
161
|
-
|
|
172
|
+
reason: mainHotUpdate.reason,
|
|
173
|
+
instructions,
|
|
162
174
|
})
|
|
163
|
-
return
|
|
164
|
-
}
|
|
165
|
-
instructions.push({
|
|
166
|
-
type: "prune",
|
|
167
|
-
boundary: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
|
|
168
|
-
acceptedBy: urlToRelativeUrl(firstUrlInfo.url, rootDirectoryUrl),
|
|
169
175
|
})
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
cause,
|
|
173
|
-
reason: mainHotUpdate.reason,
|
|
174
|
-
instructions,
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
name: "jsenv:sse_server",
|
|
180
|
-
appliesDuring: { dev: true },
|
|
181
|
-
serve: (request) => {
|
|
176
|
+
},
|
|
177
|
+
serve: (request, { rootDirectoryUrl, urlGraph }) => {
|
|
182
178
|
if (request.ressource === "/__graph__") {
|
|
183
179
|
const graphJson = JSON.stringify(urlGraph.toJSON(rootDirectoryUrl))
|
|
184
180
|
return {
|
|
@@ -190,15 +186,7 @@ export const jsenvPluginDevSSEServer = ({
|
|
|
190
186
|
body: graphJson,
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
|
-
const { accept } = request.headers
|
|
194
|
-
if (accept && accept.includes("text/event-stream")) {
|
|
195
|
-
const room = sseService.getOrCreateSSERoom(request)
|
|
196
|
-
return room.join(request)
|
|
197
|
-
}
|
|
198
189
|
return null
|
|
199
190
|
},
|
|
200
|
-
destroy: () => {
|
|
201
|
-
sseService.destroy()
|
|
202
|
-
},
|
|
203
191
|
}
|
|
204
192
|
}
|
|
@@ -3,8 +3,6 @@ import { jsenvPluginDevSSEClient } from "./dev_sse/jsenv_plugin_dev_sse_client.j
|
|
|
3
3
|
import { jsenvPluginDevSSEServer } from "./dev_sse/jsenv_plugin_dev_sse_server.js"
|
|
4
4
|
|
|
5
5
|
export const jsenvPluginAutoreload = ({
|
|
6
|
-
rootDirectoryUrl,
|
|
7
|
-
urlGraph,
|
|
8
6
|
scenario,
|
|
9
7
|
clientFileChangeCallbackList,
|
|
10
8
|
clientFilesPruneCallbackList,
|
|
@@ -16,8 +14,6 @@ export const jsenvPluginAutoreload = ({
|
|
|
16
14
|
jsenvPluginHmr(),
|
|
17
15
|
jsenvPluginDevSSEClient(),
|
|
18
16
|
jsenvPluginDevSSEServer({
|
|
19
|
-
rootDirectoryUrl,
|
|
20
|
-
urlGraph,
|
|
21
17
|
clientFileChangeCallbackList,
|
|
22
18
|
clientFilesPruneCallbackList,
|
|
23
19
|
}),
|
|
@@ -125,7 +125,6 @@ const rollupPluginJsenv = ({
|
|
|
125
125
|
usesImport:
|
|
126
126
|
rollupFileInfo.imports.length > 0 ||
|
|
127
127
|
rollupFileInfo.dynamicImports.length > 0,
|
|
128
|
-
usesExport: rollupFileInfo.exports.length > 0,
|
|
129
128
|
},
|
|
130
129
|
contentType: "text/javascript",
|
|
131
130
|
content: rollupFileInfo.code,
|