@jsenv/core 29.0.1 → 29.1.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.
Files changed (28) hide show
  1. package/dist/main.js +18307 -18350
  2. package/package.json +1 -1
  3. package/src/build/build.js +6 -6
  4. package/src/build/inject_global_version_mappings.js +1 -1
  5. package/src/{omega/server → dev}/file_service.js +5 -2
  6. package/src/dev/start_dev_server.js +124 -25
  7. package/src/{omega/server → dev}/user_agent.js +0 -0
  8. package/src/{omega → kitchen}/compat/features_compats.js +0 -0
  9. package/src/{omega → kitchen}/compat/runtime_compat.js +0 -0
  10. package/src/{omega → kitchen}/errors.js +8 -5
  11. package/src/{omega → kitchen}/fetched_content_compliance.js +0 -0
  12. package/src/{omega → kitchen}/file_url_converter.js +0 -0
  13. package/src/{omega → kitchen}/kitchen.js +0 -0
  14. package/src/{omega → kitchen}/url_graph/sort_by_dependencies.js +0 -0
  15. package/src/{omega → kitchen}/url_graph/url_graph_loader.js +0 -0
  16. package/src/{omega → kitchen}/url_graph/url_graph_report.js +0 -0
  17. package/src/{omega → kitchen}/url_graph/url_info_transformations.js +0 -0
  18. package/src/{omega → kitchen}/url_graph.js +0 -0
  19. package/src/{omega → kitchen}/url_specifier_encoding.js +0 -0
  20. package/src/{omega → kitchen}/web_workers.js +0 -0
  21. package/src/plugins/bundling/css/bundle_css.js +1 -1
  22. package/src/plugins/bundling/js_module/bundle_js_modules.js +1 -1
  23. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +1 -1
  24. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
  25. package/src/plugins/url_analysis/js/js_urls.js +1 -1
  26. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +14 -10
  27. package/src/plugins/url_resolution/node_esm_resolver.js +8 -2
  28. package/src/omega/omega_server.js +0 -167
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "29.0.1",
3
+ "version": "29.1.1",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -50,16 +50,16 @@ import {
50
50
  removeHtmlNode,
51
51
  } from "@jsenv/ast"
52
52
 
53
- import { sortByDependencies } from "../omega/url_graph/sort_by_dependencies.js"
54
- import { createUrlGraph } from "../omega/url_graph.js"
53
+ import { sortByDependencies } from "../kitchen/url_graph/sort_by_dependencies.js"
54
+ import { createUrlGraph } from "../kitchen/url_graph.js"
55
+ import { createKitchen } from "../kitchen/kitchen.js"
56
+ import { createUrlGraphLoader } from "../kitchen/url_graph/url_graph_loader.js"
57
+ import { createUrlGraphSummary } from "../kitchen/url_graph/url_graph_report.js"
58
+ import { isWebWorkerEntryPointReference } from "../kitchen/web_workers.js"
55
59
  import { jsenvPluginUrlAnalysis } from "../plugins/url_analysis/jsenv_plugin_url_analysis.js"
56
60
  import { jsenvPluginInline } from "../plugins/inline/jsenv_plugin_inline.js"
57
61
  import { jsenvPluginAsJsClassic } from "../plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js"
58
62
  import { getCorePlugins } from "../plugins/plugins.js"
59
- import { createKitchen } from "../omega/kitchen.js"
60
- import { createUrlGraphLoader } from "../omega/url_graph/url_graph_loader.js"
61
- import { createUrlGraphSummary } from "../omega/url_graph/url_graph_report.js"
62
- import { isWebWorkerEntryPointReference } from "../omega/web_workers.js"
63
63
 
64
64
  import { GRAPH } from "./graph_utils.js"
65
65
  import { createBuilUrlsGenerator } from "./build_urls_generator.js"
@@ -8,7 +8,7 @@ import {
8
8
  stringifyHtmlAst,
9
9
  } from "@jsenv/ast"
10
10
 
11
- import { isWebWorkerUrlInfo } from "@jsenv/core/src/omega/web_workers.js"
11
+ import { isWebWorkerUrlInfo } from "@jsenv/core/src/kitchen/web_workers.js"
12
12
 
13
13
  export const injectVersionMappings = async ({
14
14
  urlInfo,
@@ -8,9 +8,9 @@ import { registerDirectoryLifecycle, bufferToEtag } from "@jsenv/filesystem"
8
8
  import { urlIsInsideOf, moveUrl, asUrlWithoutSearch } from "@jsenv/urls"
9
9
  import { URL_META } from "@jsenv/url-meta"
10
10
 
11
+ import { createUrlGraph } from "@jsenv/core/src/kitchen/url_graph.js"
12
+ import { createKitchen } from "@jsenv/core/src/kitchen/kitchen.js"
11
13
  import { getCorePlugins } from "@jsenv/core/src/plugins/plugins.js"
12
- import { createUrlGraph } from "@jsenv/core/src/omega/url_graph.js"
13
- import { createKitchen } from "@jsenv/core/src/omega/kitchen.js"
14
14
  import { jsenvPluginServerEventsClientInjection } from "@jsenv/core/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js"
15
15
  import { parseUserAgentHeader } from "./user_agent.js"
16
16
 
@@ -347,6 +347,9 @@ export const createFileService = ({
347
347
  } catch (e) {
348
348
  urlInfo.error = e
349
349
  const originalError = e ? e.cause || e : e
350
+ if (originalError.asResponse) {
351
+ return originalError.asResponse()
352
+ }
350
353
  const code = originalError.code
351
354
  if (code === "PARSE_ERROR") {
352
355
  return {
@@ -6,16 +6,23 @@ import {
6
6
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
7
7
  import { createLogger, createTaskLog } from "@jsenv/log"
8
8
  import { getCallerPosition } from "@jsenv/urls"
9
+ import {
10
+ jsenvAccessControlAllowedHeaders,
11
+ startServer,
12
+ jsenvServiceCORS,
13
+ jsenvServiceErrorHandler,
14
+ } from "@jsenv/server"
15
+ import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
9
16
 
17
+ import { createServerEventsDispatcher } from "@jsenv/core/src/plugins/server_events/server_events_dispatcher.js"
10
18
  import { defaultRuntimeCompat } from "@jsenv/core/src/build/build.js"
11
19
  import { createReloadableWorker } from "@jsenv/core/src/helpers/worker_reload.js"
12
- import { startOmegaServer } from "@jsenv/core/src/omega/omega_server.js"
20
+ import { createFileService } from "./file_service.js"
13
21
 
14
22
  export const startDevServer = async ({
15
23
  signal = new AbortController().signal,
16
24
  handleSIGINT = true,
17
25
  logLevel = "info",
18
- omegaServerLogLevel = "warn",
19
26
  protocol = "http",
20
27
  // it's better to use http1 by default because it allows to get statusText in devtools
21
28
  // which gives valuable information when there is errors
@@ -26,7 +33,8 @@ export const startDevServer = async ({
26
33
  port = 3456,
27
34
  acceptAnyIp,
28
35
  keepProcessAlive = true,
29
- services,
36
+ services = [],
37
+ onStop = () => {},
30
38
 
31
39
  rootDirectoryUrl,
32
40
  clientFiles = {
@@ -134,39 +142,130 @@ export const startDevServer = async ({
134
142
  disabled: !logger.levels.info,
135
143
  })
136
144
 
137
- const server = await startOmegaServer({
138
- logLevel: omegaServerLogLevel,
145
+ const serverStopCallbacks = []
146
+ const serverEventsDispatcher = createServerEventsDispatcher()
147
+ serverStopCallbacks.push(() => {
148
+ serverEventsDispatcher.destroy()
149
+ })
150
+ const server = await startServer({
151
+ signal,
152
+ stopOnExit: false,
153
+ stopOnSIGINT: handleSIGINT,
154
+ stopOnInternalError: false,
139
155
  keepProcessAlive,
140
- acceptAnyIp,
156
+ logLevel,
157
+ startLog: false,
158
+
141
159
  protocol,
142
160
  http2,
143
161
  certificate,
144
162
  privateKey,
163
+ acceptAnyIp,
145
164
  hostname,
146
165
  port,
147
- services,
166
+ requestWaitingMs: 60_000,
167
+ services: [
168
+ jsenvServiceCORS({
169
+ accessControlAllowRequestOrigin: true,
170
+ accessControlAllowRequestMethod: true,
171
+ accessControlAllowRequestHeaders: true,
172
+ accessControlAllowedRequestHeaders: [
173
+ ...jsenvAccessControlAllowedHeaders,
174
+ "x-jsenv-execution-id",
175
+ ],
176
+ accessControlAllowCredentials: true,
177
+ timingAllowOrigin: true,
178
+ }),
179
+ ...services,
180
+ {
181
+ name: "jsenv:omega_file_service",
182
+ handleRequest: createFileService({
183
+ signal,
184
+ logLevel,
185
+ serverStopCallbacks,
186
+ serverEventsDispatcher,
148
187
 
149
- rootDirectoryUrl,
150
- scenarios: { dev: true },
151
- runtimeCompat,
188
+ rootDirectoryUrl,
189
+ scenarios: { dev: true },
190
+ runtimeCompat,
152
191
 
153
- plugins,
154
- urlAnalysis,
155
- urlResolution,
156
- fileSystemMagicRedirection,
157
- supervisor,
158
- transpilation,
159
- clientFiles,
160
- clientMainFileUrl,
161
- clientAutoreload,
162
- cooldownBetweenFileEvents,
163
- explorer,
164
- sourcemaps,
165
- sourcemapsSourcesProtocol,
166
- sourcemapsSourcesContent,
167
- writeGeneratedFiles,
192
+ plugins,
193
+ urlAnalysis,
194
+ urlResolution,
195
+ fileSystemMagicRedirection,
196
+ supervisor,
197
+ transpilation,
198
+ clientAutoreload,
199
+ clientFiles,
200
+ clientMainFileUrl,
201
+ cooldownBetweenFileEvents,
202
+ explorer,
203
+ sourcemaps,
204
+ sourcemapsSourcesProtocol,
205
+ sourcemapsSourcesContent,
206
+ writeGeneratedFiles,
207
+ }),
208
+ handleWebsocket: (websocket, { request }) => {
209
+ if (request.headers["sec-websocket-protocol"] === "jsenv") {
210
+ serverEventsDispatcher.addWebsocket(websocket, request)
211
+ }
212
+ },
213
+ },
214
+ {
215
+ name: "jsenv:omega_error_handler",
216
+ handleError: (error) => {
217
+ const getResponseForError = () => {
218
+ if (error && error.asResponse) {
219
+ return error.asResponse()
220
+ }
221
+ if (
222
+ error &&
223
+ error.statusText === "Unexpected directory operation"
224
+ ) {
225
+ return {
226
+ status: 403,
227
+ }
228
+ }
229
+ return convertFileSystemErrorToResponseProperties(error)
230
+ }
231
+ const response = getResponseForError()
232
+ if (!response) {
233
+ return null
234
+ }
235
+ const body = JSON.stringify({
236
+ status: response.status,
237
+ statusText: response.statusText,
238
+ headers: response.headers,
239
+ body: response.body,
240
+ })
241
+ return {
242
+ status: 200,
243
+ headers: {
244
+ "content-type": "application/json",
245
+ "content-length": Buffer.byteLength(body),
246
+ },
247
+ body,
248
+ }
249
+ },
250
+ },
251
+ // default error handling
252
+ jsenvServiceErrorHandler({
253
+ sendErrorDetails: true,
254
+ }),
255
+ ],
256
+ onStop: (reason) => {
257
+ onStop()
258
+ serverStopCallbacks.forEach((serverStopCallback) => {
259
+ serverStopCallback(reason)
260
+ })
261
+ serverStopCallbacks.length = 0
262
+ },
168
263
  })
169
264
  startDevServerTask.done()
265
+ if (hostname) {
266
+ delete server.origins.localip
267
+ delete server.origins.externalip
268
+ }
170
269
  logger.info(``)
171
270
  Object.keys(server.origins).forEach((key) => {
172
271
  logger.info(`- ${server.origins[key]}`)
File without changes
File without changes
@@ -23,6 +23,7 @@ export const createResolveUrlError = ({
23
23
  resolveError.name = "RESOLVE_URL_ERROR"
24
24
  resolveError.code = code
25
25
  resolveError.reason = reason
26
+ resolveError.asResponse = error.asResponse
26
27
  return resolveError
27
28
  }
28
29
  if (error.message === "NO_RESOLVE") {
@@ -64,6 +65,7 @@ export const createFetchUrlContentError = ({
64
65
  fetchError.traceLine = reference.trace.line
65
66
  fetchError.traceColumn = reference.trace.column
66
67
  fetchError.traceMessage = reference.trace.message
68
+ fetchError.asResponse = error.asResponse
67
69
  return fetchError
68
70
  }
69
71
 
@@ -104,7 +106,7 @@ export const createTransformUrlContentError = ({
104
106
  }) => {
105
107
  const transformError = new Error(
106
108
  createDetailedMessage(
107
- `Failed to transform url content of "${urlInfo.type}"`,
109
+ `"transformUrlContent" error on "${urlInfo.type}"`,
108
110
  {
109
111
  reason,
110
112
  ...details,
@@ -145,10 +147,11 @@ export const createTransformUrlContentError = ({
145
147
  })
146
148
  }
147
149
  }
150
+ transformError.asResponse = error.asResponse
148
151
  return transformError
149
152
  }
150
153
  return createFailedToTransformError({
151
- reason: `An error occured during "transformUrlContent"`,
154
+ reason: `"transformUrlContent" error on "${urlInfo.type}"`,
152
155
  ...detailsFromValueThrown(error),
153
156
  })
154
157
  }
@@ -160,8 +163,7 @@ export const createFinalizeUrlContentError = ({
160
163
  error,
161
164
  }) => {
162
165
  const finalizeError = new Error(
163
- createDetailedMessage(`Failed to finalize ${urlInfo.type} url content`, {
164
- "reason": `An error occured during "finalizeUrlContent"`,
166
+ createDetailedMessage(`"finalizeUrlContent" error on "${urlInfo.type}"`, {
165
167
  ...detailsFromValueThrown(error),
166
168
  "url": urlInfo.url,
167
169
  "url reference trace": reference.trace.message,
@@ -172,7 +174,8 @@ export const createFinalizeUrlContentError = ({
172
174
  finalizeError.cause = error
173
175
  }
174
176
  finalizeError.name = "FINALIZE_URL_CONTENT_ERROR"
175
- finalizeError.reason = `An error occured during "finalizeUrlContent"`
177
+ finalizeError.reason = `"finalizeUrlContent" error on "${urlInfo.type}"`
178
+ finalizeError.asResponse = error.asResponse
176
179
  return finalizeError
177
180
  }
178
181
 
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -9,7 +9,7 @@
9
9
  import { createMagicSource } from "@jsenv/sourcemap"
10
10
  import { applyPostCss, postCssPluginUrlVisitor } from "@jsenv/ast"
11
11
 
12
- import { sortByDependencies } from "@jsenv/core/src/omega/url_graph/sort_by_dependencies.js"
12
+ import { sortByDependencies } from "@jsenv/core/src/kitchen/url_graph/sort_by_dependencies.js"
13
13
 
14
14
  // Do not use until https://github.com/parcel-bundler/parcel-css/issues/181
15
15
  export const bundleCss = async ({ cssUrlInfos, context }) => {
@@ -6,7 +6,7 @@ import { createDetailedMessage } from "@jsenv/log"
6
6
  import { babelHelperNameFromUrl } from "@jsenv/babel-plugins"
7
7
  import { sourcemapConverter } from "@jsenv/sourcemap"
8
8
 
9
- import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
9
+ import { fileUrlConverter } from "@jsenv/core/src/kitchen/file_url_converter.js"
10
10
 
11
11
  const globalThisClientFileUrl = new URL(
12
12
  "../../transpilation/babel/global_this/client/global_this.js",
@@ -1,4 +1,4 @@
1
- import { createUrlGraphLoader } from "@jsenv/core/src/omega/url_graph/url_graph_loader.js"
1
+ import { createUrlGraphLoader } from "@jsenv/core/src/kitchen/url_graph/url_graph_loader.js"
2
2
  import { bundleJsModules } from "@jsenv/core/src/plugins/bundling/js_module/bundle_js_modules.js"
3
3
 
4
4
  import { convertJsModuleToJsClassic } from "./convert_js_module_to_js_classic.js"
@@ -2,7 +2,7 @@ import { applyBabelPlugins } from "@jsenv/ast"
2
2
  import { URL_META } from "@jsenv/url-meta"
3
3
 
4
4
  import { babelPluginInstrument } from "@jsenv/core/src/test/coverage/babel_plugin_instrument.js"
5
- import { RUNTIME_COMPAT } from "@jsenv/core/src/omega/compat/runtime_compat.js"
5
+ import { RUNTIME_COMPAT } from "@jsenv/core/src/kitchen/compat/runtime_compat.js"
6
6
  import { getBaseBabelPluginStructure } from "./helpers/babel_plugin_structure.js"
7
7
  import { babelPluginBabelHelpersAsJsenvImports } from "./helpers/babel_plugin_babel_helpers_as_jsenv_imports.js"
8
8
  import { babelPluginNewStylesheetAsJsenvImport } from "./new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js"
@@ -1,7 +1,7 @@
1
1
  import { createMagicSource } from "@jsenv/sourcemap"
2
2
  import { parseJsUrls } from "@jsenv/ast"
3
3
 
4
- import { isWebWorkerUrlInfo } from "@jsenv/core/src/omega/web_workers.js"
4
+ import { isWebWorkerUrlInfo } from "@jsenv/core/src/kitchen/web_workers.js"
5
5
 
6
6
  export const parseAndTransformJsUrls = async (urlInfo, context) => {
7
7
  const jsMentions = await parseJsUrls({
@@ -37,17 +37,19 @@ export const jsenvPluginUrlResolution = ({
37
37
  const resolveUrlUsingWebResolution = (reference) => {
38
38
  return new URL(
39
39
  reference.specifier,
40
+ // baseUrl happens second argument to new URL() is different from
41
+ // import.meta.url or document.currentScript.src
40
42
  reference.baseUrl || reference.parentUrl,
41
43
  ).href
42
44
  }
43
45
 
44
46
  const resolvers = {}
45
- Object.keys(urlResolution).forEach((referenceType) => {
46
- const resolver = urlResolution[referenceType]
47
+ Object.keys(urlResolution).forEach((urlType) => {
48
+ const resolver = urlResolution[urlType]
47
49
  if (typeof resolver !== "object") {
48
50
  throw new Error(
49
51
  `Unexpected urlResolution configuration:
50
- "${referenceType}" resolution value must be an object, got ${resolver}`,
52
+ "${urlType}" resolution value must be an object, got ${resolver}`,
51
53
  )
52
54
  }
53
55
  let { web, node_esm, ...rest } = resolver
@@ -55,13 +57,13 @@ export const jsenvPluginUrlResolution = ({
55
57
  if (unexpectedKey) {
56
58
  throw new Error(
57
59
  `Unexpected urlResolution configuration:
58
- "${referenceType}" resolution key must be "web" or "node_esm", found "${
60
+ "${urlType}" resolution key must be "web" or "node_esm", found "${
59
61
  Object.keys(rest)[0]
60
62
  }"`,
61
63
  )
62
64
  }
63
65
  if (node_esm === undefined) {
64
- node_esm = referenceType === "js_import_export"
66
+ node_esm = urlType === "js_module"
65
67
  }
66
68
  if (web === undefined) {
67
69
  web = true
@@ -69,17 +71,17 @@ export const jsenvPluginUrlResolution = ({
69
71
  if (node_esm) {
70
72
  if (node_esm === true) node_esm = {}
71
73
  const { packageConditions } = node_esm
72
- resolvers[referenceType] = createNodeEsmResolver({
74
+ resolvers[urlType] = createNodeEsmResolver({
73
75
  runtimeCompat,
74
76
  packageConditions,
75
77
  })
76
78
  } else if (web) {
77
- resolvers[referenceType] = resolveUrlUsingWebResolution
79
+ resolvers[urlType] = resolveUrlUsingWebResolution
78
80
  }
79
81
  })
80
82
 
81
- if (!resolvers["js_import_export"]) {
82
- resolvers.js_import_export = createNodeEsmResolver({ runtimeCompat })
83
+ if (!resolvers.js_module) {
84
+ resolvers.js_module = createNodeEsmResolver({ runtimeCompat })
83
85
  }
84
86
  if (!resolvers["*"]) {
85
87
  resolvers["*"] = resolveUrlUsingWebResolution
@@ -96,7 +98,9 @@ export const jsenvPluginUrlResolution = ({
96
98
  return new URL(reference.specifier.slice(1), context.rootDirectoryUrl)
97
99
  .href
98
100
  }
99
- const resolver = resolvers[reference.type] || resolvers["*"]
101
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
102
+ const urlType = parentUrlInfo ? parentUrlInfo.type : "entry_point"
103
+ const resolver = resolvers[urlType] || resolvers["*"]
100
104
  return resolver(reference, context)
101
105
  },
102
106
  // when specifier is prefixed by "file:///@ignore/"
@@ -26,11 +26,17 @@ export const createNodeEsmResolver = ({ runtimeCompat, packageConditions }) => {
26
26
  ]
27
27
 
28
28
  return (reference, context) => {
29
- const { parentUrl, specifier } = reference
29
+ if (reference.type === "package_json") {
30
+ return reference.specifier
31
+ }
32
+ const parentUrl = reference.baseUrl || reference.parentUrl
33
+ if (!parentUrl.startsWith("file:")) {
34
+ return new URL(reference.specifier, parentUrl).href
35
+ }
30
36
  const { url, type, packageUrl } = applyNodeEsmResolution({
31
37
  conditions: packageConditions,
32
38
  parentUrl,
33
- specifier,
39
+ specifier: reference.specifier,
34
40
  })
35
41
  if (context.scenarios.dev) {
36
42
  const dependsOnPackageJson =
@@ -1,167 +0,0 @@
1
- import {
2
- jsenvAccessControlAllowedHeaders,
3
- startServer,
4
- jsenvServiceCORS,
5
- jsenvServiceErrorHandler,
6
- } from "@jsenv/server"
7
- import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
8
- import { createServerEventsDispatcher } from "@jsenv/core/src/plugins/server_events/server_events_dispatcher.js"
9
-
10
- import { createFileService } from "./server/file_service.js"
11
-
12
- export const startOmegaServer = async ({
13
- signal,
14
- handleSIGINT,
15
- logLevel,
16
- protocol = "http",
17
- http2 = protocol === "https",
18
- privateKey,
19
- certificate,
20
- acceptAnyIp,
21
- hostname,
22
- port = 0,
23
- keepProcessAlive = false,
24
- onStop = () => {},
25
- services = [],
26
-
27
- rootDirectoryUrl,
28
- scenarios,
29
- runtimeCompat,
30
-
31
- plugins,
32
- urlAnalysis,
33
- urlResolution,
34
- fileSystemMagicRedirection,
35
- supervisor,
36
- transpilation,
37
- clientAutoreload,
38
- clientFiles,
39
- clientMainFileUrl,
40
- cooldownBetweenFileEvents,
41
- explorer,
42
- sourcemaps,
43
- sourcemapsSourcesProtocol,
44
- sourcemapsSourcesContent,
45
- writeGeneratedFiles,
46
- }) => {
47
- const serverStopCallbacks = []
48
- const serverEventsDispatcher = createServerEventsDispatcher()
49
- serverStopCallbacks.push(() => {
50
- serverEventsDispatcher.destroy()
51
- })
52
- const server = await startServer({
53
- signal,
54
- stopOnExit: false,
55
- stopOnSIGINT: handleSIGINT,
56
- stopOnInternalError: false,
57
- keepProcessAlive,
58
- logLevel,
59
- startLog: false,
60
-
61
- protocol,
62
- http2,
63
- certificate,
64
- privateKey,
65
- acceptAnyIp,
66
- hostname,
67
- port,
68
- requestWaitingMs: 60_1000,
69
- services: [
70
- jsenvServiceCORS({
71
- accessControlAllowRequestOrigin: true,
72
- accessControlAllowRequestMethod: true,
73
- accessControlAllowRequestHeaders: true,
74
- accessControlAllowedRequestHeaders: [
75
- ...jsenvAccessControlAllowedHeaders,
76
- "x-jsenv-execution-id",
77
- ],
78
- accessControlAllowCredentials: true,
79
- timingAllowOrigin: true,
80
- }),
81
- ...services,
82
- {
83
- name: "jsenv:omega_file_service",
84
- handleRequest: createFileService({
85
- signal,
86
- logLevel,
87
- serverStopCallbacks,
88
- serverEventsDispatcher,
89
-
90
- rootDirectoryUrl,
91
- scenarios,
92
- runtimeCompat,
93
-
94
- plugins,
95
- urlAnalysis,
96
- urlResolution,
97
- fileSystemMagicRedirection,
98
- supervisor,
99
- transpilation,
100
- clientAutoreload,
101
- clientFiles,
102
- clientMainFileUrl,
103
- cooldownBetweenFileEvents,
104
- explorer,
105
- sourcemaps,
106
- sourcemapsSourcesProtocol,
107
- sourcemapsSourcesContent,
108
- writeGeneratedFiles,
109
- }),
110
- handleWebsocket: (websocket, { request }) => {
111
- if (request.headers["sec-websocket-protocol"] === "jsenv") {
112
- serverEventsDispatcher.addWebsocket(websocket, request)
113
- }
114
- },
115
- },
116
- {
117
- name: "jsenv:omega_error_handler",
118
- handleError: (error) => {
119
- const getResponseForError = () => {
120
- if (error && error.asResponse) {
121
- return error.asResponse()
122
- }
123
- if (
124
- error &&
125
- error.statusText === "Unexpected directory operation"
126
- ) {
127
- return {
128
- status: 403,
129
- }
130
- }
131
- return convertFileSystemErrorToResponseProperties(error)
132
- }
133
- const response = getResponseForError()
134
- if (!response) {
135
- return null
136
- }
137
- const body = JSON.stringify({
138
- status: response.status,
139
- statusText: response.statusText,
140
- headers: response.headers,
141
- body: response.body,
142
- })
143
- return {
144
- status: 200,
145
- headers: {
146
- "content-type": "application/json",
147
- "content-length": Buffer.byteLength(body),
148
- },
149
- body,
150
- }
151
- },
152
- },
153
- // default error handling
154
- jsenvServiceErrorHandler({
155
- sendErrorDetails: true,
156
- }),
157
- ],
158
- onStop: (reason) => {
159
- onStop()
160
- serverStopCallbacks.forEach((serverStopCallback) => {
161
- serverStopCallback(reason)
162
- })
163
- serverStopCallbacks.length = 0
164
- },
165
- })
166
- return server
167
- }