@jsenv/core 23.8.2 → 23.8.3

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 (131) hide show
  1. package/dist/jsenv_browser_system.js +34 -34
  2. package/dist/jsenv_browser_system.js.map +119 -1048
  3. package/dist/jsenv_compile_proxy.js.map +62 -364
  4. package/dist/jsenv_exploring_index.js.map +32 -338
  5. package/dist/jsenv_exploring_redirector.js.map +76 -404
  6. package/dist/jsenv_toolbar.js.map +112 -830
  7. package/dist/jsenv_toolbar_injector.js.map +27 -307
  8. package/helpers/babel/.eslintrc.cjs +24 -24
  9. package/helpers/babel/AsyncGenerator/AsyncGenerator.js +81 -81
  10. package/helpers/babel/AwaitValue/AwaitValue.js +3 -3
  11. package/helpers/babel/applyDecoratorDescriptor/applyDecoratorDescriptor.js +33 -33
  12. package/helpers/babel/arrayLikeToArray/arrayLikeToArray.js +7 -7
  13. package/helpers/babel/arrayWithHoles/arrayWithHoles.js +4 -4
  14. package/helpers/babel/arrayWithoutHoles/arrayWithoutHoles.js +6 -6
  15. package/helpers/babel/assertThisInitialized/assertThisInitialized.js +7 -7
  16. package/helpers/babel/asyncGeneratorDelegate/asyncGeneratorDelegate.js +40 -40
  17. package/helpers/babel/asyncIterator/asyncIterator.js +12 -12
  18. package/helpers/babel/asyncToGenerator/asyncToGenerator.js +34 -34
  19. package/helpers/babel/awaitAsyncGenerator/awaitAsyncGenerator.js +5 -5
  20. package/helpers/babel/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +20 -20
  21. package/helpers/babel/classApplyDescriptorGet/classApplyDescriptorGet.js +6 -6
  22. package/helpers/babel/classApplyDescriptorSet/classApplyDescriptorSet.js +13 -13
  23. package/helpers/babel/classCallCheck/classCallCheck.js +5 -5
  24. package/helpers/babel/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -5
  25. package/helpers/babel/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -6
  26. package/helpers/babel/classExtractFieldDescriptor/classExtractFieldDescriptor.js +7 -7
  27. package/helpers/babel/classNameTDZError/classNameTDZError.js +4 -4
  28. package/helpers/babel/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +7 -7
  29. package/helpers/babel/classPrivateFieldGet/classPrivateFieldGet.js +7 -7
  30. package/helpers/babel/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +6 -6
  31. package/helpers/babel/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -5
  32. package/helpers/babel/classPrivateFieldSet/classPrivateFieldSet.js +8 -8
  33. package/helpers/babel/classPrivateMethodGet/classPrivateMethodGet.js +6 -6
  34. package/helpers/babel/classPrivateMethodSet/classPrivateMethodSet.js +3 -3
  35. package/helpers/babel/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +9 -9
  36. package/helpers/babel/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +15 -15
  37. package/helpers/babel/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +6 -6
  38. package/helpers/babel/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -3
  39. package/helpers/babel/construct/construct.js +16 -16
  40. package/helpers/babel/createClass/createClass.js +15 -15
  41. package/helpers/babel/createForOfIteratorHelper/createForOfIteratorHelper.js +60 -60
  42. package/helpers/babel/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +23 -23
  43. package/helpers/babel/createRawReactElement/createRawReactElement.js +50 -50
  44. package/helpers/babel/createSuper/createSuper.js +22 -22
  45. package/helpers/babel/decorate/decorate.js +403 -403
  46. package/helpers/babel/defaults/defaults.js +11 -11
  47. package/helpers/babel/defineEnumerableProperties/defineEnumerableProperties.js +23 -23
  48. package/helpers/babel/defineProperty/defineProperty.js +18 -18
  49. package/helpers/babel/extends/extends.js +14 -14
  50. package/helpers/babel/get/get.js +13 -13
  51. package/helpers/babel/getPrototypeOf/getPrototypeOf.js +4 -4
  52. package/helpers/babel/inherits/inherits.js +15 -15
  53. package/helpers/babel/inheritsLoose/inheritsLoose.js +7 -7
  54. package/helpers/babel/initializerDefineProperty/initializerDefineProperty.js +10 -10
  55. package/helpers/babel/initializerWarningHelper/initializerWarningHelper.js +6 -6
  56. package/helpers/babel/instanceof/instanceof.js +6 -6
  57. package/helpers/babel/interopRequireDefault/interopRequireDefault.js +3 -3
  58. package/helpers/babel/interopRequireWildcard/interopRequireWildcard.js +37 -37
  59. package/helpers/babel/isNativeFunction/isNativeFunction.js +4 -4
  60. package/helpers/babel/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -21
  61. package/helpers/babel/iterableToArray/iterableToArray.js +7 -7
  62. package/helpers/babel/iterableToArrayLimit/iterableToArrayLimit.js +36 -36
  63. package/helpers/babel/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +10 -10
  64. package/helpers/babel/jsx/jsx.js +45 -45
  65. package/helpers/babel/maybeArrayLike/maybeArrayLike.js +10 -10
  66. package/helpers/babel/newArrowCheck/newArrowCheck.js +5 -5
  67. package/helpers/babel/nonIterableRest/nonIterableRest.js +5 -5
  68. package/helpers/babel/nonIterableSpread/nonIterableSpread.js +5 -5
  69. package/helpers/babel/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -3
  70. package/helpers/babel/objectSpread/objectSpread.js +23 -23
  71. package/helpers/babel/objectSpread2/objectSpread2.js +33 -33
  72. package/helpers/babel/objectWithoutProperties/objectWithoutProperties.js +19 -19
  73. package/helpers/babel/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +13 -13
  74. package/helpers/babel/possibleConstructorReturn/possibleConstructorReturn.js +10 -10
  75. package/helpers/babel/readOnlyError/readOnlyError.js +4 -4
  76. package/helpers/babel/readme.md +9 -9
  77. package/helpers/babel/set/set.js +44 -44
  78. package/helpers/babel/setPrototypeOf/setPrototypeOf.js +6 -6
  79. package/helpers/babel/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -8
  80. package/helpers/babel/slicedToArray/slicedToArray.js +10 -10
  81. package/helpers/babel/slicedToArrayLoose/slicedToArrayLoose.js +13 -13
  82. package/helpers/babel/superPropBase/superPropBase.js +10 -10
  83. package/helpers/babel/taggedTemplateLiteral/taggedTemplateLiteral.js +10 -10
  84. package/helpers/babel/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +7 -7
  85. package/helpers/babel/tdz/tdz.js +4 -4
  86. package/helpers/babel/temporalRef/temporalRef.js +6 -6
  87. package/helpers/babel/temporalUndefined/temporalUndefined.js +3 -3
  88. package/helpers/babel/toArray/toArray.js +10 -10
  89. package/helpers/babel/toConsumableArray/toConsumableArray.js +10 -10
  90. package/helpers/babel/toPrimitive/toPrimitive.js +10 -10
  91. package/helpers/babel/toPropertyKey/toPropertyKey.js +6 -6
  92. package/helpers/babel/typeof/typeof.js +14 -14
  93. package/helpers/babel/unsupportedIterableToArray/unsupportedIterableToArray.js +12 -12
  94. package/helpers/babel/wrapAsyncGenerator/wrapAsyncGenerator.js +8 -8
  95. package/helpers/babel/wrapNativeSuper/wrapNativeSuper.js +30 -30
  96. package/helpers/babel/wrapRegExp/wrapRegExp.js +63 -63
  97. package/helpers/babel/writeOnlyError/writeOnlyError.js +4 -4
  98. package/helpers/regenerator-runtime/regenerator-runtime.js +748 -748
  99. package/{LICENSE → license} +21 -21
  100. package/package.json +1 -1
  101. package/src/buildProject.js +300 -300
  102. package/src/execute.js +184 -184
  103. package/src/internal/browser-launcher/jsenv-browser-system.js +199 -199
  104. package/src/internal/compiling/babel_plugin_import_assertions.js +121 -121
  105. package/src/internal/compiling/babel_plugin_import_metadata.js +22 -22
  106. package/src/internal/compiling/babel_plugin_import_visitor.js +84 -84
  107. package/src/internal/compiling/compile-directory/compile-asset.js +0 -7
  108. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +268 -268
  109. package/src/internal/compiling/compile-directory/updateMeta.js +154 -154
  110. package/src/internal/compiling/compile-directory/validateCache.js +265 -265
  111. package/src/internal/compiling/compileFile.js +222 -224
  112. package/src/internal/compiling/compileHtml.js +550 -550
  113. package/src/internal/compiling/createCompiledFileService.js +291 -291
  114. package/src/internal/compiling/html_source_file_service.js +404 -404
  115. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +270 -270
  116. package/src/internal/compiling/jsenvCompilerForHtml.js +308 -308
  117. package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -0
  118. package/src/internal/compiling/startCompileServer.js +1052 -1048
  119. package/src/internal/compiling/transformResultToCompilationResult.js +220 -220
  120. package/src/internal/executing/coverage/babel_plugin_instrument.js +90 -90
  121. package/src/internal/executing/coverage/reportToCoverage.js +187 -187
  122. package/src/internal/executing/executePlan.js +183 -183
  123. package/src/internal/executing/launchAndExecute.js +458 -458
  124. package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +246 -246
  125. package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +112 -112
  126. package/src/internal/runtime/s.js +727 -727
  127. package/src/internal/toolbar/jsenv-logo.svg +144 -144
  128. package/src/internal/toolbar/toolbar.main.css +196 -196
  129. package/src/internal/toolbar/toolbar.main.js +227 -227
  130. package/src/internal/url_conversion.js +317 -317
  131. package/src/startExploring.js +309 -309
@@ -1,224 +1,222 @@
1
- import {
2
- urlToRelativeUrl,
3
- fileSystemPathToUrl,
4
- resolveUrl,
5
- bufferToEtag,
6
- urlIsInsideOf,
7
- } from "@jsenv/filesystem"
8
- import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
9
-
10
- import { getOrGenerateCompiledFile } from "./compile-directory/getOrGenerateCompiledFile.js"
11
- import { updateMeta } from "./compile-directory/updateMeta.js"
12
-
13
- export const compileFile = async ({
14
- logger,
15
-
16
- projectDirectoryUrl,
17
- originalFileUrl,
18
- compiledFileUrl,
19
- fileContentFallback,
20
- projectFileRequestedCallback = () => {},
21
- request,
22
- pushResponse,
23
- compile,
24
- compileCacheStrategy,
25
- compileCacheSourcesValidation,
26
- compileCacheAssetsValidation,
27
- }) => {
28
- if (
29
- compileCacheStrategy !== "etag" &&
30
- compileCacheStrategy !== "mtime" &&
31
- compileCacheStrategy !== "none"
32
- ) {
33
- throw new Error(
34
- `compileCacheStrategy must be "etag", "mtime" or "none", got ${compileCacheStrategy}`,
35
- )
36
- }
37
-
38
- const clientCacheDisabled = request.headers["cache-control"] === "no-cache"
39
-
40
- try {
41
- const { meta, compileResult, compileResultStatus, timing } =
42
- await getOrGenerateCompiledFile({
43
- logger,
44
- projectDirectoryUrl,
45
- originalFileUrl,
46
- compiledFileUrl,
47
- fileContentFallback,
48
- request,
49
- compileCacheStrategy,
50
- compileCacheSourcesValidation,
51
- compileCacheAssetsValidation,
52
- compile,
53
- })
54
-
55
- if (compileCacheStrategy === "etag" && !compileResult.compiledEtag) {
56
- // happens when file was just compiled so etag was not computed
57
- compileResult.compiledEtag = bufferToEtag(
58
- Buffer.from(compileResult.compiledSource),
59
- )
60
- }
61
-
62
- if (compileCacheStrategy === "mtime" && !compileResult.compiledMtime) {
63
- // happens when file was just compiled so it's not yet written on filesystem
64
- // Here we know the compiled file will be written on the filesystem
65
- // We could wait for the file to be written before responding to the client
66
- // but it could delay a bit the response.
67
- // Inside "updateMeta" the file might be written synchronously
68
- // or batched to be written later for perf reasons.
69
- // From this side of the code we would like to be agnostic about this to allow
70
- // eventual perf improvments in that field.
71
- // For this reason the "mtime" we send to the client is decided here
72
- // by "compileResult.compiledMtime = Date.now()"
73
- // "updateMeta" will respect this and when it will write the compiled file it will
74
- // use "utimes" to ensure the file mtime is the one we sent to the client
75
- // This is important so that a request sending an mtime
76
- // can be compared with the compiled file mtime on the filesystem
77
- // In the end etag is preffered over mtime by default so this will rarely
78
- // be useful
79
- compileResult.compiledMtime = Date.now()
80
- }
81
-
82
- const {
83
- contentType,
84
- compiledEtag,
85
- compiledMtime,
86
- compiledSource,
87
- responseHeaders = {},
88
- } = compileResult
89
-
90
- if (compileResultStatus !== "cached" && compileCacheStrategy !== "none") {
91
- updateMeta({
92
- logger,
93
- meta,
94
- compileResult,
95
- compileResultStatus,
96
- compiledFileUrl,
97
- // originalFileUrl,
98
- })
99
- }
100
-
101
- compileResult.sources.forEach((source) => {
102
- const sourceFileUrl = resolveUrl(source, compiledFileUrl)
103
- projectFileRequestedCallback(
104
- urlToRelativeUrl(sourceFileUrl, projectDirectoryUrl),
105
- request,
106
- )
107
- })
108
-
109
- if (request.http2) {
110
- compileResult.dependencies.forEach((dependency) => {
111
- if (
112
- compileResult.contentType === "application/javascript" &&
113
- !dependency.startsWith("./")
114
- ) {
115
- // js might use importmap to remap bare specifiers
116
- // so ignore thoose deps (ideally we would resolve using importmap)
117
- return
118
- }
119
-
120
- const requestUrl = resolveUrl(request.ressource, request.origin)
121
- const dependencyUrl = resolveUrl(dependency, requestUrl)
122
- if (!urlIsInsideOf(dependencyUrl, request.origin)) {
123
- // ignore external urls
124
- return
125
- }
126
- if (dependencyUrl.startsWith("data:")) {
127
- return
128
- }
129
- const dependencyRelativeUrl = urlToRelativeUrl(
130
- dependencyUrl,
131
- request.origin,
132
- )
133
- pushResponse({ path: `/${dependencyRelativeUrl}` })
134
- })
135
- }
136
-
137
- // when a compiled version of the source file was just created or updated
138
- // we don't want to rely on filesystem because we might want to delay
139
- // when the file is written for perf reasons
140
- // Moreover we already got the data in RAM
141
- const respondUsingRAM = (finalizeResponse = () => {}) => {
142
- const response = {
143
- status: 200,
144
- headers: {
145
- "content-length": Buffer.byteLength(compiledSource),
146
- "content-type": contentType,
147
- ...responseHeaders,
148
- },
149
- body: compiledSource,
150
- timing,
151
- }
152
- finalizeResponse(response)
153
- return response
154
- }
155
-
156
- if (!clientCacheDisabled && compileCacheStrategy === "etag") {
157
- if (
158
- request.headers["if-none-match"] &&
159
- compileResultStatus === "cached"
160
- ) {
161
- return {
162
- status: 304,
163
- timing,
164
- }
165
- }
166
- return respondUsingRAM((response) => {
167
- // eslint-disable-next-line dot-notation
168
- response.headers["etag"] = compiledEtag
169
- })
170
- }
171
-
172
- if (!clientCacheDisabled && compileCacheStrategy === "mtime") {
173
- if (
174
- request.headers["if-modified-since"] &&
175
- compileResultStatus === "cached"
176
- ) {
177
- return {
178
- status: 304,
179
- timing,
180
- }
181
- }
182
- return respondUsingRAM((response) => {
183
- response.headers["last-modified"] = new Date(
184
- compiledMtime,
185
- ).toUTCString()
186
- })
187
- }
188
-
189
- return respondUsingRAM()
190
- } catch (error) {
191
- if (error && error.code === "PARSE_ERROR") {
192
- const { data } = error
193
- const { filename } = data
194
- if (filename) {
195
- const relativeUrl = urlToRelativeUrl(
196
- fileSystemPathToUrl(filename),
197
- projectDirectoryUrl,
198
- )
199
- projectFileRequestedCallback(relativeUrl, request)
200
- }
201
- // on the correspondig file
202
- const json = JSON.stringify(data)
203
-
204
- return {
205
- status: 500,
206
- statusText: "parse error",
207
- headers: {
208
- "cache-control": "no-store",
209
- "content-length": Buffer.byteLength(json),
210
- "content-type": "application/json",
211
- },
212
- body: json,
213
- }
214
- }
215
-
216
- if (error && error.statusText === "Unexpected directory operation") {
217
- return {
218
- status: 403,
219
- }
220
- }
221
-
222
- return convertFileSystemErrorToResponseProperties(error)
223
- }
224
- }
1
+ import {
2
+ urlToRelativeUrl,
3
+ fileSystemPathToUrl,
4
+ resolveUrl,
5
+ bufferToEtag,
6
+ urlIsInsideOf,
7
+ } from "@jsenv/filesystem"
8
+ import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
9
+
10
+ import { getOrGenerateCompiledFile } from "./compile-directory/getOrGenerateCompiledFile.js"
11
+ import { updateMeta } from "./compile-directory/updateMeta.js"
12
+
13
+ export const compileFile = async ({
14
+ logger,
15
+
16
+ projectDirectoryUrl,
17
+ originalFileUrl,
18
+ compiledFileUrl,
19
+ fileContentFallback,
20
+ projectFileRequestedCallback = () => {},
21
+ request,
22
+ pushResponse,
23
+ compile,
24
+ compileCacheStrategy,
25
+ compileCacheSourcesValidation,
26
+ compileCacheAssetsValidation,
27
+ }) => {
28
+ if (
29
+ compileCacheStrategy !== "etag" &&
30
+ compileCacheStrategy !== "mtime" &&
31
+ compileCacheStrategy !== "none"
32
+ ) {
33
+ throw new Error(
34
+ `compileCacheStrategy must be "etag", "mtime" or "none", got ${compileCacheStrategy}`,
35
+ )
36
+ }
37
+
38
+ const clientCacheDisabled = request.headers["cache-control"] === "no-cache"
39
+
40
+ try {
41
+ const { meta, compileResult, compileResultStatus, timing } =
42
+ await getOrGenerateCompiledFile({
43
+ logger,
44
+ projectDirectoryUrl,
45
+ originalFileUrl,
46
+ compiledFileUrl,
47
+ fileContentFallback,
48
+ request,
49
+ compileCacheStrategy,
50
+ compileCacheSourcesValidation,
51
+ compileCacheAssetsValidation,
52
+ compile,
53
+ })
54
+
55
+ if (compileCacheStrategy === "etag" && !compileResult.compiledEtag) {
56
+ // happens when file was just compiled so etag was not computed
57
+ compileResult.compiledEtag = bufferToEtag(
58
+ Buffer.from(compileResult.compiledSource),
59
+ )
60
+ }
61
+
62
+ if (compileCacheStrategy === "mtime" && !compileResult.compiledMtime) {
63
+ // happens when file was just compiled so it's not yet written on filesystem
64
+ // Here we know the compiled file will be written on the filesystem
65
+ // We could wait for the file to be written before responding to the client
66
+ // but it could delay a bit the response.
67
+ // Inside "updateMeta" the file might be written synchronously
68
+ // or batched to be written later for perf reasons.
69
+ // From this side of the code we would like to be agnostic about this to allow
70
+ // eventual perf improvments in that field.
71
+ // For this reason the "mtime" we send to the client is decided here
72
+ // by "compileResult.compiledMtime = Date.now()"
73
+ // "updateMeta" will respect this and when it will write the compiled file it will
74
+ // use "utimes" to ensure the file mtime is the one we sent to the client
75
+ // This is important so that a request sending an mtime
76
+ // can be compared with the compiled file mtime on the filesystem
77
+ // In the end etag is preffered over mtime by default so this will rarely
78
+ // be useful
79
+ compileResult.compiledMtime = Date.now()
80
+ }
81
+
82
+ const {
83
+ contentType,
84
+ compiledEtag,
85
+ compiledMtime,
86
+ compiledSource,
87
+ responseHeaders = {},
88
+ } = compileResult
89
+
90
+ if (compileResultStatus !== "cached" && compileCacheStrategy !== "none") {
91
+ updateMeta({
92
+ logger,
93
+ meta,
94
+ compileResult,
95
+ compileResultStatus,
96
+ compiledFileUrl,
97
+ // originalFileUrl,
98
+ })
99
+ }
100
+
101
+ compileResult.sources.forEach((source) => {
102
+ const sourceFileUrl = resolveUrl(source, compiledFileUrl)
103
+ projectFileRequestedCallback(
104
+ urlToRelativeUrl(sourceFileUrl, projectDirectoryUrl),
105
+ request,
106
+ )
107
+ })
108
+
109
+ if (
110
+ request.http2 &&
111
+ // js resolution is special, we cannot just do resolveUrl of the import specifier
112
+ // because there can be importmap (bare specifier, import without extension, custom remapping, ...)
113
+ // And we would push 404 to the browser
114
+ // Until we implement import map resolution pushing ressource for js imports is disabled
115
+ compileResult.contentType !== "application/javascript"
116
+ ) {
117
+ compileResult.dependencies.forEach((dependency) => {
118
+ const requestUrl = resolveUrl(request.ressource, request.origin)
119
+ const dependencyUrl = resolveUrl(dependency, requestUrl)
120
+ if (!urlIsInsideOf(dependencyUrl, request.origin)) {
121
+ // ignore external urls
122
+ return
123
+ }
124
+ if (dependencyUrl.startsWith("data:")) {
125
+ return
126
+ }
127
+ const dependencyRelativeUrl = urlToRelativeUrl(
128
+ dependencyUrl,
129
+ request.origin,
130
+ )
131
+ pushResponse({ path: `/${dependencyRelativeUrl}` })
132
+ })
133
+ }
134
+
135
+ // when a compiled version of the source file was just created or updated
136
+ // we don't want to rely on filesystem because we might want to delay
137
+ // when the file is written for perf reasons
138
+ // Moreover we already got the data in RAM
139
+ const respondUsingRAM = (finalizeResponse = () => {}) => {
140
+ const response = {
141
+ status: 200,
142
+ headers: {
143
+ "content-length": Buffer.byteLength(compiledSource),
144
+ "content-type": contentType,
145
+ ...responseHeaders,
146
+ },
147
+ body: compiledSource,
148
+ timing,
149
+ }
150
+ finalizeResponse(response)
151
+ return response
152
+ }
153
+
154
+ if (!clientCacheDisabled && compileCacheStrategy === "etag") {
155
+ if (
156
+ request.headers["if-none-match"] &&
157
+ compileResultStatus === "cached"
158
+ ) {
159
+ return {
160
+ status: 304,
161
+ timing,
162
+ }
163
+ }
164
+ return respondUsingRAM((response) => {
165
+ // eslint-disable-next-line dot-notation
166
+ response.headers["etag"] = compiledEtag
167
+ })
168
+ }
169
+
170
+ if (!clientCacheDisabled && compileCacheStrategy === "mtime") {
171
+ if (
172
+ request.headers["if-modified-since"] &&
173
+ compileResultStatus === "cached"
174
+ ) {
175
+ return {
176
+ status: 304,
177
+ timing,
178
+ }
179
+ }
180
+ return respondUsingRAM((response) => {
181
+ response.headers["last-modified"] = new Date(
182
+ compiledMtime,
183
+ ).toUTCString()
184
+ })
185
+ }
186
+
187
+ return respondUsingRAM()
188
+ } catch (error) {
189
+ if (error && error.code === "PARSE_ERROR") {
190
+ const { data } = error
191
+ const { filename } = data
192
+ if (filename) {
193
+ const relativeUrl = urlToRelativeUrl(
194
+ fileSystemPathToUrl(filename),
195
+ projectDirectoryUrl,
196
+ )
197
+ projectFileRequestedCallback(relativeUrl, request)
198
+ }
199
+ // on the correspondig file
200
+ const json = JSON.stringify(data)
201
+
202
+ return {
203
+ status: 500,
204
+ statusText: "parse error",
205
+ headers: {
206
+ "cache-control": "no-store",
207
+ "content-length": Buffer.byteLength(json),
208
+ "content-type": "application/json",
209
+ },
210
+ body: json,
211
+ }
212
+ }
213
+
214
+ if (error && error.statusText === "Unexpected directory operation") {
215
+ return {
216
+ status: 403,
217
+ }
218
+ }
219
+
220
+ return convertFileSystemErrorToResponseProperties(error)
221
+ }
222
+ }