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

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 +545 -0
  2. package/dist/event_source_client.js.map +187 -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 +30 -28
  11. package/readme.md +6 -14
  12. package/src/build/build.js +943 -555
  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 +192 -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 +136 -30
  22. package/src/execute/execute.js +31 -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 +482 -304
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +53 -25
  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 +98 -48
  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 +2 -2
  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 +2 -2
  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 +30 -18
  123. package/src/test/execute_test_plan.js +23 -8
  124. package/src/test/logs_file_execution.js +9 -8
  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,4 +1,22 @@
1
- import { createControlledProcess } from "./controlled_process.js"
1
+ import { fork } from "node:child_process"
2
+ import { urlToFileSystemPath } from "@jsenv/filesystem"
3
+ import { createDetailedMessage } from "@jsenv/logger"
4
+ import {
5
+ Abort,
6
+ raceCallbacks,
7
+ createCallbackListNotifiedOnce,
8
+ } from "@jsenv/abort"
9
+ import { uneval } from "@jsenv/uneval"
10
+
11
+ import { memoize } from "@jsenv/utils/memoize/memoize.js"
12
+ import { createChildExecOptions } from "./child_exec_options.js"
13
+ import { ExecOptions } from "./exec_options.js"
14
+ import { killProcessTree } from "./kill_process_tree.js"
15
+
16
+ const NODE_CONTROLLABLE_FILE_URL = new URL(
17
+ "./controllable_file.mjs",
18
+ import.meta.url,
19
+ ).href
2
20
 
3
21
  export const nodeProcess = {
4
22
  name: "node",
@@ -8,33 +26,32 @@ export const nodeProcess = {
8
26
  nodeProcess.run = async ({
9
27
  signal = new AbortController().signal,
10
28
  logger,
11
- logProcessCommand,
29
+ logProcessCommand = false,
12
30
  rootDirectoryUrl,
13
31
  fileRelativeUrl,
14
32
 
15
33
  keepRunning,
16
34
  gracefulStopAllocatedMs = 4000,
17
35
  stopSignal,
18
- onStop,
19
- onError,
20
36
  onConsole,
21
- onResult,
22
37
 
23
- measurePerformance,
24
- collectPerformance,
25
38
  collectCoverage = false,
26
39
  coverageForceIstanbul,
40
+ collectPerformance,
27
41
 
28
42
  debugPort,
29
43
  debugMode,
30
44
  debugModeInheritBreak,
31
45
  env,
32
- inheritProcessEnv,
46
+ inheritProcessEnv = true,
33
47
  commandLineOptions = [],
34
- stdin,
35
- stdout,
36
- stderr,
48
+ stdin = "pipe",
49
+ stdout = "pipe",
50
+ stderr = "pipe",
37
51
  }) => {
52
+ if (env !== undefined && typeof env !== "object") {
53
+ throw new TypeError(`env must be an object, got ${env}`)
54
+ }
38
55
  env = {
39
56
  ...env,
40
57
  COVERAGE_ENABLED: collectCoverage,
@@ -49,44 +66,268 @@ nodeProcess.run = async ({
49
66
  "--experimental-import-meta-resolve",
50
67
  ...commandLineOptions,
51
68
  ]
52
- const { stop, requestActionOnChildProcess } = await createControlledProcess({
69
+
70
+ const cleanupCallbackList = createCallbackListNotifiedOnce()
71
+ const cleanup = async (reason) => {
72
+ await cleanupCallbackList.notify({ reason })
73
+ }
74
+
75
+ const childExecOptions = await createChildExecOptions({
53
76
  signal,
54
- logger,
55
77
  debugPort,
56
78
  debugMode,
57
79
  debugModeInheritBreak,
58
- env,
59
- inheritProcessEnv,
60
- commandLineOptions,
61
- stdin,
62
- stdout,
63
- stderr,
64
- logProcessCommand,
65
-
66
- stopSignal,
67
- onStop,
68
- onError,
69
- onConsole,
70
80
  })
71
- const namespace = await requestActionOnChildProcess({
72
- signal,
73
- actionType: "execute-using-dynamic-import",
74
- actionParams: {
75
- fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
76
- measurePerformance,
77
- collectPerformance,
78
- collectCoverage,
81
+ const execArgv = ExecOptions.toExecArgv({
82
+ ...childExecOptions,
83
+ ...ExecOptions.fromExecArgv(commandLineOptions),
84
+ })
85
+ const envForChildProcess = {
86
+ ...(inheritProcessEnv ? process.env : {}),
87
+ ...env,
88
+ }
89
+ logger[logProcessCommand ? "info" : "debug"](
90
+ `${process.argv[0]} ${execArgv.join(" ")} ${urlToFileSystemPath(
91
+ NODE_CONTROLLABLE_FILE_URL,
92
+ )}`,
93
+ )
94
+ const childProcess = fork(urlToFileSystemPath(NODE_CONTROLLABLE_FILE_URL), {
95
+ execArgv,
96
+ // silent: true
97
+ stdio: ["pipe", "pipe", "pipe", "ipc"],
98
+ env: envForChildProcess,
99
+ })
100
+ logger.debug(
101
+ createDetailedMessage(`child process forked (pid ${childProcess.pid})`, {
102
+ "execArgv": execArgv.join(`\n`),
103
+ "custom env": JSON.stringify(env, null, " "),
104
+ }),
105
+ )
106
+ // if we pass stream, pipe them https://github.com/sindresorhus/execa/issues/81
107
+ if (typeof stdin === "object") {
108
+ stdin.pipe(childProcess.stdin)
109
+ }
110
+ if (typeof stdout === "object") {
111
+ childProcess.stdout.pipe(stdout)
112
+ }
113
+ if (typeof stderr === "object") {
114
+ childProcess.stderr.pipe(stderr)
115
+ }
116
+ const childProcessReadyPromise = new Promise((resolve) => {
117
+ onceProcessMessage(childProcess, "ready", resolve)
118
+ })
119
+ const removeOutputListener = installProcessOutputListener(
120
+ childProcess,
121
+ ({ type, text }) => {
122
+ onConsole({ type, text })
79
123
  },
124
+ )
125
+ const stop = memoize(async ({ gracefulStopAllocatedMs } = {}) => {
126
+ // all libraries are facing problem on windows when trying
127
+ // to kill a process spawning other processes.
128
+ // "killProcessTree" is theorically correct but sometimes keep process handing forever.
129
+ // Inside GitHub workflow the whole Virtual machine gets unresponsive and ends up being killed
130
+ // There is no satisfying solution to this problem so we stick to the basic
131
+ // childProcess.kill()
132
+ if (process.platform === "win32") {
133
+ childProcess.kill()
134
+ return
135
+ }
136
+ if (gracefulStopAllocatedMs) {
137
+ try {
138
+ await killProcessTree(childProcess.pid, {
139
+ signal: GRACEFUL_STOP_SIGNAL,
140
+ timeout: gracefulStopAllocatedMs,
141
+ })
142
+ return
143
+ } catch (e) {
144
+ if (e.code === "TIMEOUT") {
145
+ logger.debug(
146
+ `kill with SIGTERM because gracefulStop still pending after ${gracefulStopAllocatedMs}ms`,
147
+ )
148
+ await killProcessTree(childProcess.pid, {
149
+ signal: GRACEFUL_STOP_FAILED_SIGNAL,
150
+ })
151
+ return
152
+ }
153
+ throw e
154
+ }
155
+ }
156
+ await killProcessTree(childProcess.pid, { signal: STOP_SIGNAL })
157
+ return
80
158
  })
81
- onResult({
82
- status: "completed",
83
- namespace,
159
+
160
+ const actionOperation = Abort.startOperation()
161
+ actionOperation.addAbortSignal(signal)
162
+ const winnerPromise = new Promise((resolve) => {
163
+ raceCallbacks(
164
+ {
165
+ // https://nodejs.org/api/child_process.html#child_process_event_disconnect
166
+ // disconnect: (cb) => {
167
+ // return onceProcessEvent(childProcess, "disconnect", cb)
168
+ // },
169
+ // https://nodejs.org/api/child_process.html#child_process_event_error
170
+ error: (cb) => {
171
+ return onceProcessEvent(childProcess, "error", cb)
172
+ },
173
+ exit: (cb) => {
174
+ return onceProcessEvent(childProcess, "exit", (code, signal) => {
175
+ cb({ code, signal })
176
+ })
177
+ },
178
+ response: (cb) => {
179
+ onceProcessMessage(childProcess, "action-result", cb)
180
+ },
181
+ },
182
+ resolve,
183
+ )
84
184
  })
185
+ const getResult = async () => {
186
+ actionOperation.throwIfAborted()
187
+ await childProcessReadyPromise
188
+ actionOperation.throwIfAborted()
189
+ await sendToProcess(childProcess, "action", {
190
+ actionType: "execute-using-dynamic-import",
191
+ actionParams: {
192
+ fileUrl: new URL(fileRelativeUrl, rootDirectoryUrl).href,
193
+ collectPerformance,
194
+ },
195
+ })
196
+ const winner = await winnerPromise
197
+ if (winner.name === "error") {
198
+ const error = winner.data
199
+ removeOutputListener()
200
+ return {
201
+ status: "errored",
202
+ error,
203
+ }
204
+ }
205
+ if (winner.name === "exit") {
206
+ const { code } = winner.data
207
+ await cleanup("process exit")
208
+ if (code === 12) {
209
+ return {
210
+ status: "errored",
211
+ error: new Error(
212
+ `node process exited with 12 (the forked child process wanted to use a non-available port for debug)`,
213
+ ),
214
+ }
215
+ }
216
+ if (
217
+ code === null ||
218
+ code === 0 ||
219
+ code === SIGINT_EXIT_CODE ||
220
+ code === SIGTERM_EXIT_CODE ||
221
+ code === SIGABORT_EXIT_CODE
222
+ ) {
223
+ return {
224
+ status: "errored",
225
+ error: new Error(`node process exited during execution`),
226
+ }
227
+ }
228
+ // process.exit(1) in child process or process.exitCode = 1 + process.exit()
229
+ // means there was an error even if we don't know exactly what.
230
+ return {
231
+ status: "errored",
232
+ error: new Error(
233
+ `node process exited with code ${code} during execution`,
234
+ ),
235
+ }
236
+ }
237
+ const { status, value } = winner.data
238
+ if (status === "action-failed") {
239
+ return {
240
+ status: "errored",
241
+ error: value,
242
+ }
243
+ }
244
+ return {
245
+ status: "completed",
246
+ ...value,
247
+ }
248
+ }
249
+
250
+ let result
251
+ try {
252
+ result = await getResult()
253
+ } catch (e) {
254
+ result = {
255
+ status: "errored",
256
+ error: e,
257
+ }
258
+ }
85
259
  if (keepRunning) {
86
260
  stopSignal.notify = stop
87
- return
261
+ } else {
262
+ await stop({
263
+ gracefulStopAllocatedMs,
264
+ })
88
265
  }
89
- await stop({
90
- gracefulStopAllocatedMs,
266
+ await actionOperation.end()
267
+ return result
268
+ }
269
+
270
+ // https://nodejs.org/api/process.html#process_signal_events
271
+ const SIGINT_SIGNAL_NUMBER = 2
272
+ const SIGABORT_SIGNAL_NUMBER = 6
273
+ const SIGTERM_SIGNAL_NUMBER = 15
274
+ const SIGINT_EXIT_CODE = 128 + SIGINT_SIGNAL_NUMBER
275
+ const SIGABORT_EXIT_CODE = 128 + SIGABORT_SIGNAL_NUMBER
276
+ const SIGTERM_EXIT_CODE = 128 + SIGTERM_SIGNAL_NUMBER
277
+ // http://man7.org/linux/man-pages/man7/signal.7.html
278
+ // https:// github.com/nodejs/node/blob/1d9511127c419ec116b3ddf5fc7a59e8f0f1c1e4/lib/internal/child_process.js#L472
279
+ const GRACEFUL_STOP_SIGNAL = "SIGTERM"
280
+ const STOP_SIGNAL = "SIGKILL"
281
+ // it would be more correct if GRACEFUL_STOP_FAILED_SIGNAL was SIGHUP instead of SIGKILL.
282
+ // but I'm not sure and it changes nothing so just use SIGKILL
283
+ const GRACEFUL_STOP_FAILED_SIGNAL = "SIGKILL"
284
+
285
+ const sendToProcess = async (childProcess, type, data) => {
286
+ const source = uneval(data, { functionAllowed: true })
287
+ return new Promise((resolve, reject) => {
288
+ childProcess.send({ type, data: source }, (error) => {
289
+ if (error) {
290
+ reject(error)
291
+ } else {
292
+ resolve()
293
+ }
294
+ })
91
295
  })
92
296
  }
297
+
298
+ const installProcessOutputListener = (childProcess, callback) => {
299
+ // beware that we may receive ansi output here, should not be a problem but keep that in mind
300
+ const stdoutDataCallback = (chunk) => {
301
+ callback({ type: "log", text: String(chunk) })
302
+ }
303
+ childProcess.stdout.on("data", stdoutDataCallback)
304
+ const stdErrorDataCallback = (chunk) => {
305
+ callback({ type: "error", text: String(chunk) })
306
+ }
307
+ childProcess.stderr.on("data", stdErrorDataCallback)
308
+ return () => {
309
+ childProcess.stdout.removeListener("data", stdoutDataCallback)
310
+ childProcess.stderr.removeListener("data", stdoutDataCallback)
311
+ }
312
+ }
313
+
314
+ const onceProcessMessage = (childProcess, type, callback) => {
315
+ const onmessage = (message) => {
316
+ if (message.type === type) {
317
+ childProcess.removeListener("message", onmessage)
318
+ // eslint-disable-next-line no-eval
319
+ callback(message.data ? eval(`(${message.data})`) : "")
320
+ }
321
+ }
322
+ childProcess.on("message", onmessage)
323
+ return () => {
324
+ childProcess.removeListener("message", onmessage)
325
+ }
326
+ }
327
+
328
+ const onceProcessEvent = (childProcess, type, callback) => {
329
+ childProcess.once(type, callback)
330
+ return () => {
331
+ childProcess.removeListener(type, callback)
332
+ }
333
+ }
@@ -0,0 +1 @@
1
+ export const jsenvRootDirectoryUrl = new URL("../", import.meta.url).href
@@ -1,13 +1,11 @@
1
1
  // correspond to dynamic import
2
- export const defaultRuntimeSupport = {
2
+ export const defaultRuntimeCompat = {
3
3
  // android: "8",
4
4
  chrome: "63",
5
5
  edge: "79",
6
- electron: "8.1",
7
6
  firefox: "67",
8
- ios: "11",
7
+ ios: "11.3",
9
8
  opera: "50",
10
9
  safari: "11.3",
11
- node: "13.2",
12
- samsung: "8.0",
10
+ samsung: "8.2",
13
11
  }
@@ -1,4 +1,4 @@
1
- export const featuresCompatMap = {
1
+ export const featureCompats = {
2
2
  script_type_module: {
3
3
  edge: "16",
4
4
  firefox: "60",
@@ -9,6 +9,15 @@ export const featuresCompatMap = {
9
9
  android: "61",
10
10
  samsung: "8.2",
11
11
  },
12
+ document_current_script: {
13
+ edge: "12",
14
+ firefox: "4",
15
+ chrome: "29",
16
+ safari: "8",
17
+ opera: "16",
18
+ android: "4.4",
19
+ samsung: "4",
20
+ },
12
21
  import_meta: {
13
22
  chrome: "64",
14
23
  edge: "79",
@@ -18,13 +27,16 @@ export const featuresCompatMap = {
18
27
  ios: "12",
19
28
  android: "9",
20
29
  },
30
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
21
31
  import_dynamic: {
32
+ android: "8",
33
+ chrome: "63",
22
34
  edge: "79",
23
35
  firefox: "67",
24
- chrome: "63",
25
- safari: "11.3",
36
+ ios: "11.3",
26
37
  opera: "50",
27
- android: "8",
38
+ safari: "11.3",
39
+ samsung: "8.0",
28
40
  node: "13.2",
29
41
  },
30
42
  top_level_await: {
@@ -52,6 +64,7 @@ export const featuresCompatMap = {
52
64
  chrome: "93",
53
65
  edge: "93",
54
66
  },
67
+ import_type_text: {},
55
68
  // https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet#browser_compatibility
56
69
  new_stylesheet: {
57
70
  chrome: "73",
@@ -59,6 +72,18 @@ export const featuresCompatMap = {
59
72
  opera: "53",
60
73
  android: "73",
61
74
  },
75
+ // https://caniuse.com/?search=worker
76
+ worker: {
77
+ ie: "10",
78
+ edge: "12",
79
+ firefox: "3.5",
80
+ chrome: "4",
81
+ opera: "11.5",
82
+ safari: "4",
83
+ ios: "5",
84
+ android: "4.4",
85
+ },
86
+ // https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker#browser_compatibility
62
87
  worker_type_module: {
63
88
  chrome: "80",
64
89
  edge: "80",
@@ -66,6 +91,32 @@ export const featuresCompatMap = {
66
91
  android: "80",
67
92
  },
68
93
  worker_importmap: {},
94
+ service_worker: {
95
+ edge: "17",
96
+ firefox: "44",
97
+ chrome: "40",
98
+ safari: "11.1",
99
+ opera: "27",
100
+ ios: "11.3",
101
+ android: "12.12",
102
+ },
103
+ service_worker_type_module: {
104
+ chrome: "80",
105
+ edge: "80",
106
+ opera: "67",
107
+ android: "80",
108
+ },
109
+ shared_worker: {
110
+ chrome: "4",
111
+ edge: "79",
112
+ firefox: "29",
113
+ opera: "10.6",
114
+ },
115
+ shared_worker_type_module: {
116
+ chrome: "80",
117
+ edge: "80",
118
+ opera: "67",
119
+ },
69
120
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis#browser_compatibility
70
121
  global_this: {
71
122
  edge: "79",
@@ -88,4 +139,15 @@ export const featuresCompatMap = {
88
139
  samsung: "8",
89
140
  electron: "3",
90
141
  },
142
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#browser_compatibility
143
+ template_literals: {
144
+ chrome: "41",
145
+ edge: "12",
146
+ firefox: "34",
147
+ opera: "28",
148
+ safari: "9",
149
+ ios: "9",
150
+ android: "4",
151
+ node: "4",
152
+ },
91
153
  }
@@ -0,0 +1,50 @@
1
+ import { findHighestVersion } from "@jsenv/utils/semantic_versioning/highest_version.js"
2
+ import { featureCompats } from "./features_compats.js"
3
+
4
+ export const RUNTIME_COMPAT = {
5
+ featureCompats,
6
+
7
+ add: (originalRuntimeCompat, feature) => {
8
+ const featureCompat = getFeatureCompat(feature)
9
+ const runtimeCompat = {
10
+ ...originalRuntimeCompat,
11
+ }
12
+ Object.keys(featureCompat).forEach((runtimeName) => {
13
+ const firstVersion = originalRuntimeCompat[runtimeName]
14
+ const secondVersion = featureCompat[runtimeName]
15
+ runtimeCompat[runtimeName] = firstVersion
16
+ ? findHighestVersion(firstVersion, secondVersion)
17
+ : secondVersion
18
+ })
19
+ return runtimeCompat
20
+ },
21
+
22
+ isSupported: (runtimeCompat, feature) => {
23
+ const featureCompat = getFeatureCompat(feature)
24
+ const runtimeNames = Object.keys(runtimeCompat)
25
+ const runtimeWithoutCompat = runtimeNames.find((runtimeName) => {
26
+ const runtimeVersion = runtimeCompat[runtimeName]
27
+ const runtimeVersionCompatible = featureCompat[runtimeName] || "Infinity"
28
+ const highestVersion = findHighestVersion(
29
+ runtimeVersion,
30
+ runtimeVersionCompatible,
31
+ )
32
+ return highestVersion !== runtimeVersion
33
+ })
34
+ return !runtimeWithoutCompat
35
+ },
36
+ }
37
+
38
+ const getFeatureCompat = (feature) => {
39
+ if (typeof feature === "string") {
40
+ const compat = featureCompats[feature]
41
+ if (!compat) {
42
+ throw new Error(`"${feature}" feature is unknown`)
43
+ }
44
+ return compat
45
+ }
46
+ if (typeof feature !== "object") {
47
+ throw new TypeError(`feature must be a string or an object, got ${feature}`)
48
+ }
49
+ return feature
50
+ }