@jsenv/core 27.0.0-alpha.15 → 27.0.0-alpha.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.0.0-alpha.15",
3
+ "version": "27.0.0-alpha.18",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -66,7 +66,7 @@
66
66
  "@jsenv/node-esm-resolution": "0.0.2",
67
67
  "@jsenv/server": "12.6.1",
68
68
  "@jsenv/uneval": "1.6.0",
69
- "@jsenv/utils": "1.1.0",
69
+ "@jsenv/utils": "1.2.1",
70
70
  "construct-style-sheets-polyfill": "3.1.0",
71
71
  "cssnano": "5.1.7",
72
72
  "cssnano-preset-default": "5.2.7",
@@ -309,10 +309,25 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
309
309
  if (reference.specifier[0] === "#") {
310
310
  reference.external = true
311
311
  }
312
- const url =
312
+ let url =
313
313
  reference.specifier[0] === "/"
314
314
  ? new URL(reference.specifier.slice(1), buildDirectoryUrl).href
315
315
  : new URL(reference.specifier, reference.parentUrl).href
316
+ const parentIsFromBundle = Boolean(
317
+ bundleUrlInfos[reference.parentUrl],
318
+ )
319
+ // urls inside css bundled by parcel
320
+ // contains url relative to the bundle file (which is considered inside build directory)
321
+ // if the file is not itself a bundle file it must be resolved against
322
+ // the original css url
323
+ if (
324
+ parentIsFromBundle &&
325
+ !bundleUrlInfos[url] &&
326
+ urlIsInsideOf(url, buildDirectoryUrl)
327
+ ) {
328
+ const parentRawUrl = rawUrls[reference.parentUrl]
329
+ url = new URL(reference.specifier, parentRawUrl).href
330
+ }
316
331
  const urlRedirected = rawUrlRedirections[url]
317
332
  return urlRedirected || url
318
333
  },
@@ -26,6 +26,7 @@ import { createLogger } from "@jsenv/logger"
26
26
 
27
27
  import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
28
28
  import { watchFiles } from "@jsenv/utils/file_watcher/file_watcher.js"
29
+ import { setupFileRestart } from "@jsenv/utils/file_watcher/file_restart.js"
29
30
  import { executeCommand } from "@jsenv/utils/command/command.js"
30
31
 
31
32
  export const startBuildServer = async ({
@@ -46,6 +47,7 @@ export const startBuildServer = async ({
46
47
  buildCommand,
47
48
  watchedFilePatterns,
48
49
  cooldownBetweenFileEvents,
50
+ autorestart,
49
51
  }) => {
50
52
  const operation = Abort.startOperation()
51
53
  operation.addAbortSignal(signal)
@@ -59,118 +61,128 @@ export const startBuildServer = async ({
59
61
  )
60
62
  })
61
63
  }
62
- const logger = createLogger({ logLevel })
64
+ setupFileRestart({
65
+ signal: operation.signal,
66
+ autorestart,
67
+ injectedUrlsToWatch: [
68
+ new URL("package.json", rootDirectoryUrl),
69
+ new URL("jsenv.config.mjs", rootDirectoryUrl),
70
+ ],
71
+ job: async () => {
72
+ const logger = createLogger({ logLevel })
63
73
 
64
- let buildPromise
65
- let abortController
66
- const runBuild = async () => {
67
- const buildTask = createTaskLog(logger, `execute build command`)
68
- abortController = new AbortController()
69
- operation.addAbortCallback(() => {
70
- abortController.abort()
71
- })
72
- buildPromise = executeCommand(buildCommand, {
73
- cwd: rootDirectoryUrl,
74
- logLevel: buildCommandLogLevel,
75
- signal: abortController.signal,
76
- })
77
- try {
78
- await buildPromise
79
- buildTask.done()
80
- } catch (e) {
81
- if (e.code === "ABORT_ERR") {
82
- buildTask.fail(`execute build command aborted`)
83
- } else {
84
- buildTask.fail()
85
- throw e
74
+ let buildPromise
75
+ let abortController
76
+ const runBuild = async () => {
77
+ const buildTask = createTaskLog(logger, `execute build command`)
78
+ abortController = new AbortController()
79
+ operation.addAbortCallback(() => {
80
+ abortController.abort()
81
+ })
82
+ buildPromise = executeCommand(buildCommand, {
83
+ cwd: rootDirectoryUrl,
84
+ logLevel: buildCommandLogLevel,
85
+ signal: abortController.signal,
86
+ })
87
+ try {
88
+ await buildPromise
89
+ buildTask.done()
90
+ } catch (e) {
91
+ if (e.code === "ABORT_ERR") {
92
+ buildTask.fail(`execute build command aborted`)
93
+ } else {
94
+ buildTask.fail()
95
+ throw e
96
+ }
97
+ }
86
98
  }
87
- }
88
- }
89
99
 
90
- const startServerTask = createTaskLog(logger, "start build server")
91
- const server = await startServer({
92
- signal,
93
- stopOnExit: false,
94
- stopOnSIGINT: false,
95
- stopOnInternalError: false,
96
- keepProcessAlive: true,
97
- logLevel,
98
- startLog: false,
100
+ const startServerTask = createTaskLog(logger, "start build server")
101
+ const server = await startServer({
102
+ signal,
103
+ stopOnExit: false,
104
+ stopOnSIGINT: false,
105
+ stopOnInternalError: false,
106
+ keepProcessAlive: true,
107
+ logLevel,
108
+ startLog: false,
99
109
 
100
- protocol,
101
- http2,
102
- certificate,
103
- privateKey,
104
- listenAnyIp,
105
- ip,
106
- port,
107
- plugins: {
108
- ...pluginCORS({
109
- accessControlAllowRequestOrigin: true,
110
- accessControlAllowRequestMethod: true,
111
- accessControlAllowRequestHeaders: true,
112
- accessControlAllowedRequestHeaders: [
113
- ...jsenvAccessControlAllowedHeaders,
114
- "x-jsenv-execution-id",
115
- ],
116
- accessControlAllowCredentials: true,
117
- }),
118
- ...pluginServerTiming(),
119
- ...pluginRequestWaitingCheck({
120
- requestWaitingMs: 60 * 1000,
121
- }),
122
- },
123
- sendErrorDetails: true,
124
- requestToResponse: async (request) => {
125
- await buildPromise
126
- const urlIsVersioned = new URL(
127
- request.ressource,
128
- request.origin,
129
- ).searchParams.has("v")
110
+ protocol,
111
+ http2,
112
+ certificate,
113
+ privateKey,
114
+ listenAnyIp,
115
+ ip,
116
+ port,
117
+ plugins: {
118
+ ...pluginCORS({
119
+ accessControlAllowRequestOrigin: true,
120
+ accessControlAllowRequestMethod: true,
121
+ accessControlAllowRequestHeaders: true,
122
+ accessControlAllowedRequestHeaders: [
123
+ ...jsenvAccessControlAllowedHeaders,
124
+ "x-jsenv-execution-id",
125
+ ],
126
+ accessControlAllowCredentials: true,
127
+ }),
128
+ ...pluginServerTiming(),
129
+ ...pluginRequestWaitingCheck({
130
+ requestWaitingMs: 60 * 1000,
131
+ }),
132
+ },
133
+ sendErrorDetails: true,
134
+ requestToResponse: async (request) => {
135
+ await buildPromise
136
+ const urlIsVersioned = new URL(
137
+ request.ressource,
138
+ request.origin,
139
+ ).searchParams.has("v")
130
140
 
131
- return fetchFileSystem(
132
- new URL(request.ressource.slice(1), buildDirectoryUrl),
133
- {
134
- headers: request.headers,
135
- cacheControl: urlIsVersioned
136
- ? `private,max-age=${SECONDS_IN_30_DAYS},immutable`
137
- : "private,max-age=0,must-revalidate",
138
- etagEnabled: true,
139
- compressionEnabled: !request.pathname.endsWith(".mp4"),
140
- rootDirectoryUrl: buildDirectoryUrl,
141
- canReadDirectory: true,
141
+ return fetchFileSystem(
142
+ new URL(request.ressource.slice(1), buildDirectoryUrl),
143
+ {
144
+ headers: request.headers,
145
+ cacheControl: urlIsVersioned
146
+ ? `private,max-age=${SECONDS_IN_30_DAYS},immutable`
147
+ : "private,max-age=0,must-revalidate",
148
+ etagEnabled: true,
149
+ compressionEnabled: !request.pathname.endsWith(".mp4"),
150
+ rootDirectoryUrl: buildDirectoryUrl,
151
+ canReadDirectory: true,
152
+ },
153
+ )
142
154
  },
143
- )
144
- },
145
- })
146
- startServerTask.done()
147
- logger.info(``)
148
- Object.keys(server.origins).forEach((key) => {
149
- logger.info(`- ${server.origins[key]}`)
150
- })
151
- logger.info(``)
155
+ })
156
+ startServerTask.done()
157
+ logger.info(``)
158
+ Object.keys(server.origins).forEach((key) => {
159
+ logger.info(`- ${server.origins[key]}`)
160
+ })
161
+ logger.info(``)
152
162
 
153
- const unregisterDirectoryLifecyle = watchFiles({
154
- rootDirectoryUrl,
155
- watchedFilePatterns,
156
- cooldownBetweenFileEvents,
157
- fileChangeCallback: ({ relativeUrl, event }) => {
158
- abortController.abort()
159
- // setTimeout is to ensure the abortController.abort() above
160
- // is properly taken into account so that logs about abort comes first
161
- // then logs about re-running the build happens
162
- setTimeout(() => {
163
- logger.info(`${relativeUrl} ${event} -> rebuild`)
164
- runBuild()
163
+ const unregisterDirectoryLifecyle = watchFiles({
164
+ rootDirectoryUrl,
165
+ watchedFilePatterns,
166
+ cooldownBetweenFileEvents,
167
+ fileChangeCallback: ({ url, event }) => {
168
+ abortController.abort()
169
+ // setTimeout is to ensure the abortController.abort() above
170
+ // is properly taken into account so that logs about abort comes first
171
+ // then logs about re-running the build happens
172
+ setTimeout(() => {
173
+ logger.info(
174
+ `${url.slice(rootDirectoryUrl.length)} ${event} -> rebuild`,
175
+ )
176
+ runBuild()
177
+ })
178
+ },
179
+ })
180
+ operation.addAbortCallback(() => {
181
+ unregisterDirectoryLifecyle()
165
182
  })
183
+ runBuild()
166
184
  },
167
185
  })
168
- operation.addAbortCallback(() => {
169
- unregisterDirectoryLifecyle()
170
- })
171
- runBuild()
172
-
173
- return server
174
186
  }
175
187
 
176
188
  const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30
@@ -134,8 +134,8 @@ export const jsenvPluginDevSSEServer = ({
134
134
  watchedFilePatterns,
135
135
  cooldownBetweenFileEvents,
136
136
  serverEventCallbackList,
137
- onFileChange: ({ relativeUrl, event }) => {
138
- const url = new URL(relativeUrl, rootDirectoryUrl).href
137
+ onFileChange: ({ url, event }) => {
138
+ const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
139
139
  const urlInfo = urlGraph.urlInfos[url]
140
140
  // file not part of dependency graph
141
141
  if (!urlInfo) {
@@ -1,16 +1,20 @@
1
1
  import { bundleWithParcel } from "@jsenv/utils/css_ast/parcel_css.js"
2
2
 
3
- export const bundleCss = ({ cssUrlInfos, context }) => {
3
+ export const bundleCss = async ({ cssUrlInfos, context }) => {
4
4
  const bundledCssUrlInfos = {}
5
5
  cssUrlInfos.forEach((cssUrlInfo) => {
6
6
  const { code, map } = bundleWithParcel(cssUrlInfo, context)
7
+ const content = String(code)
8
+ const sourcemap = map
9
+ // here we need to replace css urls to ensure
10
+ // all urls targets the correct stuff
7
11
  bundledCssUrlInfos[cssUrlInfo.url] = {
8
12
  data: {
9
13
  generatedBy: "parcel",
10
14
  },
11
15
  contentType: "text/css",
12
- content: String(code),
13
- sourcemap: map,
16
+ content,
17
+ sourcemap,
14
18
  }
15
19
  })
16
20
  return bundledCssUrlInfos