@jsenv/core 27.0.0-alpha.54 → 27.0.0-alpha.55

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.54",
3
+ "version": "27.0.0-alpha.55",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -224,16 +224,6 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
224
224
  })
225
225
  })
226
226
  const addToBundlerIfAny = (rawUrlInfo) => {
227
- if (
228
- // entry point must be given to the bundler (rollup)
229
- // so that the bundler know it's an entry point, even if it has no dependency
230
- // this way the bundler can share code properly and avoid inlining an entry point
231
- // if it's used by an other entry point
232
- !rawUrlInfo.data.isEntryPoint &&
233
- rawUrlInfo.dependencies.size === 0
234
- ) {
235
- return
236
- }
237
227
  const bundler = bundlers[rawUrlInfo.type]
238
228
  if (bundler) {
239
229
  bundler.urlInfos.push(rawUrlInfo)
@@ -740,12 +730,12 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
740
730
  buildInlineContents[buildRelativeUrl] = urlInfo.content
741
731
  } else {
742
732
  buildFileContents[buildRelativeUrl] = urlInfo.content
733
+ const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
734
+ urlInfo.url,
735
+ buildDirectoryUrl,
736
+ )
737
+ buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
743
738
  }
744
- const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
745
- urlInfo.url,
746
- buildDirectoryUrl,
747
- )
748
- buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
749
739
  })
750
740
  if (writeOnFileSystem) {
751
741
  if (buildDirectoryClean) {
@@ -68,6 +68,7 @@ export const startBuildServer = async ({
68
68
  buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
69
69
 
70
70
  const reloadableProcess = await initReloadableProcess({
71
+ signal,
71
72
  handleSIGINT,
72
73
  ...(buildServerAutoreload
73
74
  ? {
@@ -192,10 +192,7 @@ export const createKitchen = ({
192
192
  Object.keys(returnValue).forEach((key) => {
193
193
  referenceUrlObject.searchParams.set(key, returnValue[key])
194
194
  })
195
- reference.generatedUrl = referenceUrlObject.href.replace(
196
- /[=](?=&|$)/g,
197
- "",
198
- )
195
+ reference.generatedUrl = normalizeUrl(referenceUrlObject.href)
199
196
  },
200
197
  )
201
198
  const returnValue = pluginController.callHooksUntil(
@@ -654,8 +651,6 @@ export const createKitchen = ({
654
651
  const prepareEntryPoint = (params) => {
655
652
  const entryReference = createReference(params)
656
653
  const entryUrlInfo = resolveReference(entryReference)
657
- // I should likely delete urlInfo.sourcemap
658
- // otherwise it is reused when page is reloaded
659
654
  return [entryReference, entryUrlInfo]
660
655
  }
661
656
 
@@ -20,6 +20,11 @@ export const createFileService = ({
20
20
  urlGraph,
21
21
  scenario,
22
22
  }
23
+ const augmentResponseContext = {
24
+ rootDirectoryUrl,
25
+ urlGraph,
26
+ scenario,
27
+ }
23
28
 
24
29
  const getResponse = async (request) => {
25
30
  // serve file inside ".jsenv" directory
@@ -58,9 +63,19 @@ export const createFileService = ({
58
63
  reference.parentUrl,
59
64
  )
60
65
  try {
61
- // urlInfo objects are reused, they must be "reset" before cooking then again
62
- if (!urlInfo.isInline && !urlInfo.type === "sourcemap") {
63
- urlGraph.resetUrlInfo(urlInfo)
66
+ // urlInfo objects are reused, they must be "reset" before cooking them again
67
+ if (
68
+ urlInfo.contentEtag &&
69
+ !urlInfo.isInline &&
70
+ urlInfo.type !== "sourcemap"
71
+ ) {
72
+ urlInfo.sourcemap = null
73
+ urlInfo.sourcemapReference = null
74
+ urlInfo.content = null
75
+ urlInfo.originalContent = null
76
+ urlInfo.type = null
77
+ urlInfo.subtype = null
78
+ urlInfo.timing = {}
64
79
  }
65
80
  const { runtimeName, runtimeVersion } = parseUserAgentHeader(
66
81
  request.headers["user-agent"],
@@ -92,7 +107,7 @@ export const createFileService = ({
92
107
  kitchen.pluginController.callHooks(
93
108
  "augmentResponse",
94
109
  { reference, urlInfo },
95
- {},
110
+ augmentResponseContext,
96
111
  (returnValue) => {
97
112
  response = composeTwoResponses(response, returnValue)
98
113
  },
@@ -15,16 +15,6 @@ export const createUrlGraph = ({
15
15
  }
16
16
  }
17
17
  }
18
- const resetUrlInfo = (urlInfo) => {
19
- urlInfo.sourcemap = null
20
- urlInfo.sourcemapReference = null
21
- urlInfo.content = null
22
- urlInfo.originalContent = null
23
- urlInfo.type = null
24
- urlInfo.subtype = null
25
- urlInfo.data = {}
26
- urlInfo.timing = {}
27
- }
28
18
 
29
19
  const reuseOrCreateUrlInfo = (url) => {
30
20
  const existingUrlInfo = urlInfos[url]
@@ -160,7 +150,6 @@ export const createUrlGraph = ({
160
150
  reuseOrCreateUrlInfo,
161
151
  getUrlInfo,
162
152
  deleteUrlInfo,
163
- resetUrlInfo,
164
153
  inferReference,
165
154
  findDependent,
166
155
  updateReferences,
@@ -0,0 +1,34 @@
1
+ export const jsenvPluginCacheControl = () => {
2
+ return {
3
+ name: "jsenv:cache_control",
4
+ appliesDuring: {
5
+ dev: true,
6
+ test: true,
7
+ },
8
+ augmentResponse: ({ reference }, context) => {
9
+ if (context.scenario === "dev") {
10
+ // During dev, all files are put into browser cache for 1 hour because:
11
+ // 1: Browser cache is a temporary directory created by playwright
12
+ // 2: We assume source files won't be modified while tests are running
13
+ return {
14
+ headers: {
15
+ "cache-control": `private,max-age=3600,immutable`,
16
+ },
17
+ }
18
+ }
19
+ if (
20
+ reference.searchParams.has("v") &&
21
+ !reference.searchParams.has("hmr")
22
+ ) {
23
+ return {
24
+ headers: {
25
+ "cache-control": `private,max-age=${SECONDS_IN_30_DAYS},immutable`,
26
+ },
27
+ }
28
+ }
29
+ return null
30
+ },
31
+ }
32
+ }
33
+
34
+ const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30
@@ -17,6 +17,7 @@ import { jsenvPluginBundling } from "./bundling/jsenv_plugin_bundling.js"
17
17
  import { jsenvPluginMinification } from "./minification/jsenv_plugin_minification.js"
18
18
  import { jsenvPluginImportMetaHot } from "./import_meta_hot/jsenv_plugin_import_meta_hot.js"
19
19
  import { jsenvPluginAutoreload } from "./autoreload/jsenv_plugin_autoreload.js"
20
+ import { jsenvPluginCacheControl } from "./cache_control/jsenv_plugin_cache_control.js"
20
21
 
21
22
  export const getCorePlugins = ({
22
23
  rootDirectoryUrl,
@@ -68,7 +69,6 @@ export const getCorePlugins = ({
68
69
  jsenvPluginInjectGlobals(injectedGlobals),
69
70
  jsenvPluginCommonJsGlobals(),
70
71
  jsenvPluginImportMetaScenarios(),
71
- // jsenvPluginWorkers(),
72
72
 
73
73
  jsenvPluginBundling(bundling),
74
74
  jsenvPluginMinification(minification),
@@ -87,5 +87,6 @@ export const getCorePlugins = ({
87
87
  }),
88
88
  ]
89
89
  : []),
90
+ jsenvPluginCacheControl(),
90
91
  ]
91
92
  }
@@ -1,7 +1,12 @@
1
1
  import { getBabelHelperFileUrl, requireBabelPlugin } from "@jsenv/babel-plugins"
2
2
  import { babelPluginCompatMap } from "./babel_plugins_compatibility.js"
3
3
 
4
- export const getBaseBabelPluginStructure = ({ url, isSupported }) => {
4
+ export const getBaseBabelPluginStructure = ({
5
+ url,
6
+ isSupported,
7
+ // isJsModule,
8
+ // getImportSpecifier,
9
+ }) => {
5
10
  const isBabelPluginNeeded = (babelPluginName) => {
6
11
  return !isSupported(babelPluginCompatMap[babelPluginName])
7
12
  }
@@ -35,6 +40,12 @@ export const getBaseBabelPluginStructure = ({ url, isSupported }) => {
35
40
  requireBabelPlugin("babel-plugin-transform-async-to-promises"),
36
41
  {
37
42
  topLevelAwait: "ignore", // will be handled by "jsenv:top_level_await" plugin
43
+ externalHelpers: false,
44
+ // enable once https://github.com/rpetrich/babel-plugin-transform-async-to-promises/pull/83
45
+ // externalHelpers: isJsModule,
46
+ // externalHelpersPath: isJsModule ? getImportSpecifier(
47
+ // "babel-plugin-transform-async-to-promises/helpers.mjs",
48
+ // ) : null
38
49
  },
39
50
  ]
40
51
  }
@@ -33,27 +33,29 @@ export const jsenvPluginBabel = ({ getCustomBabelPlugins } = {}) => {
33
33
  )
34
34
  }
35
35
 
36
- const { referenceUtils } = context
37
36
  const isSupported = (feature) =>
38
37
  RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature)
38
+ const getImportSpecifier = (clientFileUrl) => {
39
+ const [reference] = context.referenceUtils.inject({
40
+ type: "js_import_export",
41
+ expectedType: "js_module",
42
+ specifier: clientFileUrl,
43
+ })
44
+ return JSON.parse(reference.generatedSpecifier)
45
+ }
46
+
39
47
  const babelPluginStructure = getBaseBabelPluginStructure({
40
48
  url: urlInfo.url,
41
49
  isSupported,
42
50
  isWorkerContext,
51
+ isJsModule,
52
+ getImportSpecifier,
43
53
  })
44
54
  if (getCustomBabelPlugins) {
45
55
  Object.assign(babelPluginStructure, getCustomBabelPlugins(context))
46
56
  }
47
57
 
48
58
  if (isJsModule) {
49
- const getImportSpecifier = (clientFileUrl) => {
50
- const [reference] = referenceUtils.inject({
51
- type: "js_import_export",
52
- expectedType: "js_module",
53
- specifier: clientFileUrl,
54
- })
55
- return JSON.parse(reference.generatedSpecifier)
56
- }
57
59
  if (!isSupported("global_this")) {
58
60
  babelPluginStructure["global-this-as-jsenv-import"] = [
59
61
  babelPluginGlobalThisAsJsenvImport,
@@ -24,6 +24,16 @@ export const jsenvPluginTopLevelAwait = () => {
24
24
  // Maybe we could pass target: "es6" when we support arrow function
25
25
  // https://github.com/rpetrich/babel-plugin-transform-async-to-promises/blob/92755ff8c943c97596523e586b5fa515c2e99326/async-to-promises.ts#L55
26
26
  topLevelAwait: "simple",
27
+ // enable once https://github.com/rpetrich/babel-plugin-transform-async-to-promises/pull/83
28
+ // externalHelpers: true,
29
+ // externalHelpersPath: JSON.parse(
30
+ // context.referenceUtils.inject({
31
+ // type: "js_import_export",
32
+ // expectedType: "js_module",
33
+ // specifier:
34
+ // "babel-plugin-transform-async-to-promises/helpers.mjs",
35
+ // })[0],
36
+ // ),
27
37
  },
28
38
  ],
29
39
  ],
@@ -1,7 +1,7 @@
1
- export const jsenvPluginUrlVersion = ({ longTermCache = true } = {}) => {
1
+ export const jsenvPluginUrlVersion = () => {
2
2
  return {
3
3
  name: "jsenv:url_version",
4
- appliesDuring: "*", // maybe only during dev?
4
+ appliesDuring: "*",
5
5
  redirectUrl: (reference) => {
6
6
  // "v" search param goal is to enable long-term cache
7
7
  // for server response headers
@@ -24,24 +24,5 @@ export const jsenvPluginUrlVersion = ({ longTermCache = true } = {}) => {
24
24
  v: reference.data.version,
25
25
  }
26
26
  },
27
- augmentResponse: ({ reference }) => {
28
- if (!longTermCache) {
29
- return null
30
- }
31
- if (!reference.searchParams.has("v")) {
32
- return null
33
- }
34
- if (reference.searchParams.has("hmr")) {
35
- return null
36
- }
37
- // When url is versioned put it in browser cache for 30 days
38
- return {
39
- headers: {
40
- "cache-control": `private,max-age=${SECONDS_IN_30_DAYS},immutable`,
41
- },
42
- }
43
- },
44
27
  }
45
28
  }
46
-
47
- const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30