@jsenv/core 23.8.2 → 23.8.7

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 (133) hide show
  1. package/dist/jsenv_browser_system.js +46 -39
  2. package/dist/jsenv_browser_system.js.map +14 -14
  3. package/dist/jsenv_compile_proxy.js.map +6 -6
  4. package/dist/jsenv_exploring_index.js.map +5 -5
  5. package/dist/jsenv_exploring_redirector.js.map +12 -12
  6. package/dist/jsenv_toolbar.js.map +7 -7
  7. package/dist/jsenv_toolbar_injector.js.map +5 -5
  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 +2 -2
  101. package/src/buildProject.js +300 -300
  102. package/src/execute.js +184 -184
  103. package/src/internal/browser-launcher/jsenv-browser-system.js +203 -199
  104. package/src/internal/building/buildUsingRollup.js +2 -10
  105. package/src/internal/compiling/babel_plugin_import_assertions.js +121 -121
  106. package/src/internal/compiling/babel_plugin_import_metadata.js +22 -22
  107. package/src/internal/compiling/babel_plugin_import_visitor.js +84 -84
  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 +233 -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 +403 -404
  115. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +272 -270
  116. package/src/internal/compiling/jsenvCompilerForHtml.js +374 -308
  117. package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -0
  118. package/src/internal/compiling/startCompileServer.js +1086 -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 +193 -187
  122. package/src/internal/executing/executePlan.js +183 -183
  123. package/src/internal/executing/launchAndExecute.js +458 -458
  124. package/src/internal/generateGroupMap/featuresCompatMap.js +29 -0
  125. package/src/internal/generateGroupMap/jsenvBabelPluginCompatMap.js +1 -8
  126. package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +246 -246
  127. package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +112 -112
  128. package/src/internal/runtime/s.js +727 -727
  129. package/src/internal/toolbar/jsenv-logo.svg +144 -144
  130. package/src/internal/toolbar/toolbar.main.css +196 -196
  131. package/src/internal/toolbar/toolbar.main.js +227 -227
  132. package/src/internal/url_conversion.js +317 -317
  133. package/src/startExploring.js +309 -309
@@ -1,224 +1,233 @@
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
+ // we MUST await updateMeta otherwise we might get 404
92
+ // when serving sourcemap files
93
+ await updateMeta({
94
+ logger,
95
+ meta,
96
+ compileResult,
97
+ compileResultStatus,
98
+ compiledFileUrl,
99
+ // originalFileUrl,
100
+ })
101
+ }
102
+
103
+ compileResult.sources.forEach((source) => {
104
+ const sourceFileUrl = resolveUrl(source, compiledFileUrl)
105
+ projectFileRequestedCallback(
106
+ urlToRelativeUrl(sourceFileUrl, projectDirectoryUrl),
107
+ request,
108
+ )
109
+ })
110
+
111
+ if (
112
+ request.http2 &&
113
+ // js resolution is special, we cannot just do resolveUrl of the import specifier
114
+ // because there can be importmap (bare specifier, import without extension, custom remapping, ...)
115
+ // And we would push 404 to the browser
116
+ // Until we implement import map resolution pushing ressource for js imports is disabled
117
+ compileResult.contentType !== "application/javascript"
118
+ ) {
119
+ compileResult.dependencies.forEach((dependency) => {
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
+ "cache-control": "no-store",
148
+ ...responseHeaders,
149
+ },
150
+ body: compiledSource,
151
+ timing,
152
+ }
153
+ finalizeResponse(response)
154
+ return response
155
+ }
156
+
157
+ if (!clientCacheDisabled && compileCacheStrategy === "etag") {
158
+ if (
159
+ request.headers["if-none-match"] &&
160
+ compileResultStatus === "cached"
161
+ ) {
162
+ return {
163
+ status: 304,
164
+ headers: {
165
+ "cache-control": "private,max-age=0,must-revalidate",
166
+ },
167
+ timing,
168
+ }
169
+ }
170
+ return respondUsingRAM((response) => {
171
+ // eslint-disable-next-line dot-notation
172
+ response.headers["etag"] = compiledEtag
173
+ response.headers["cache-control"] = "private,max-age=0,must-revalidate"
174
+ })
175
+ }
176
+
177
+ if (!clientCacheDisabled && compileCacheStrategy === "mtime") {
178
+ if (
179
+ request.headers["if-modified-since"] &&
180
+ compileResultStatus === "cached"
181
+ ) {
182
+ return {
183
+ status: 304,
184
+ headers: {
185
+ "cache-control": "private,max-age=0,must-revalidate",
186
+ },
187
+ timing,
188
+ }
189
+ }
190
+ return respondUsingRAM((response) => {
191
+ response.headers["last-modified"] = new Date(
192
+ compiledMtime,
193
+ ).toUTCString()
194
+ response.headers["cache-control"] = "private,max-age=0,must-revalidate"
195
+ })
196
+ }
197
+
198
+ return respondUsingRAM()
199
+ } catch (error) {
200
+ if (error && error.code === "PARSE_ERROR") {
201
+ const { data } = error
202
+ const { filename } = data
203
+ if (filename) {
204
+ const relativeUrl = urlToRelativeUrl(
205
+ fileSystemPathToUrl(filename),
206
+ projectDirectoryUrl,
207
+ )
208
+ projectFileRequestedCallback(relativeUrl, request)
209
+ }
210
+ // on the correspondig file
211
+ const json = JSON.stringify(data)
212
+
213
+ return {
214
+ status: 500,
215
+ statusText: "parse error",
216
+ headers: {
217
+ "cache-control": "no-store",
218
+ "content-length": Buffer.byteLength(json),
219
+ "content-type": "application/json",
220
+ },
221
+ body: json,
222
+ }
223
+ }
224
+
225
+ if (error && error.statusText === "Unexpected directory operation") {
226
+ return {
227
+ status: 403,
228
+ }
229
+ }
230
+
231
+ return convertFileSystemErrorToResponseProperties(error)
232
+ }
233
+ }