@jsenv/core 31.0.0 → 31.1.0

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/dist/main.js CHANGED
@@ -20,6 +20,7 @@ import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes
20
20
  import { createRequire } from "node:module";
21
21
  import babelParser from "@babel/parser";
22
22
  import { bundleJsModules } from "@jsenv/plugin-bundling";
23
+ import { replacePlaceholders } from "@jsenv/plugin-placeholders";
23
24
  import v8, { takeCoverage } from "node:v8";
24
25
  import wrapAnsi from "wrap-ansi";
25
26
  import stripAnsi from "strip-ansi";
@@ -9225,7 +9226,13 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
9225
9226
  } = urlInfo;
9226
9227
  if (generatedUrl && generatedUrl.startsWith("file:")) {
9227
9228
  if (urlInfo.type === "directory") ; else if (urlInfo.content === null) ; else {
9228
- writeFileSync(new URL(generatedUrl), urlInfo.content);
9229
+ let contentIsInlined = urlInfo.isInline;
9230
+ if (contentIsInlined && context.supervisor && urlGraph.getUrlInfo(urlInfo.inlineUrlSite.url).type === "html") {
9231
+ contentIsInlined = false;
9232
+ }
9233
+ if (!contentIsInlined) {
9234
+ writeFileSync(new URL(generatedUrl), urlInfo.content);
9235
+ }
9229
9236
  const {
9230
9237
  sourcemapGeneratedUrl,
9231
9238
  sourcemap
@@ -17971,6 +17978,30 @@ const babelPluginMetadataImportMetaScenarios = () => {
17971
17978
  };
17972
17979
  };
17973
17980
 
17981
+ /*
17982
+ * Source code can contain the following
17983
+ * - __dev__
17984
+ * - __build__
17985
+ * A global will be injected with true/false when needed
17986
+ */
17987
+ const jsenvPluginGlobalScenarios = () => {
17988
+ const transformIfNeeded = (urlInfo, context) => {
17989
+ return replacePlaceholders(urlInfo, {
17990
+ false: context.dev,
17991
+ true: context.build
17992
+ });
17993
+ };
17994
+ return {
17995
+ name: "jsenv:global_scenario",
17996
+ appliesDuring: "*",
17997
+ transformUrlContent: {
17998
+ js_classic: transformIfNeeded,
17999
+ js_module: transformIfNeeded,
18000
+ html: transformIfNeeded
18001
+ }
18002
+ };
18003
+ };
18004
+
17974
18005
  const jsenvPluginCssTranspilation = () => {
17975
18006
  return {
17976
18007
  name: "jsenv:css_transpilation",
@@ -20303,7 +20334,7 @@ const getCorePlugins = ({
20303
20334
  runtimeCompat,
20304
20335
  clientMainFileUrl,
20305
20336
  urlResolution
20306
- }), jsenvPluginUrlVersion(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginNodeRuntime({
20337
+ }), jsenvPluginUrlVersion(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginGlobalScenarios(), jsenvPluginNodeRuntime({
20307
20338
  runtimeCompat
20308
20339
  }), jsenvPluginImportMetaHot(), ...(clientAutoreload ? [jsenvPluginAutoreload({
20309
20340
  ...clientAutoreload,
@@ -22256,6 +22287,7 @@ const createFileService = ({
22256
22287
  logLevel,
22257
22288
  serverStopCallbacks,
22258
22289
  serverEventsDispatcher,
22290
+ contextCache,
22259
22291
  rootDirectoryUrl,
22260
22292
  runtimeCompat,
22261
22293
  plugins,
@@ -22319,7 +22351,6 @@ const createFileService = ({
22319
22351
  }
22320
22352
  });
22321
22353
  serverStopCallbacks.push(stopWatchingClientFiles);
22322
- const contextCache = new Map();
22323
22354
  const getOrCreateContext = request => {
22324
22355
  const {
22325
22356
  runtimeName,
@@ -22380,6 +22411,7 @@ const createFileService = ({
22380
22411
  cacheControl,
22381
22412
  ribbon
22382
22413
  })],
22414
+ supervisor,
22383
22415
  minification: false,
22384
22416
  sourcemaps,
22385
22417
  sourcemapsSourcesProtocol,
@@ -22849,6 +22881,7 @@ const startDevServer = async ({
22849
22881
  serverStopCallbacks.push(() => {
22850
22882
  serverEventsDispatcher.destroy();
22851
22883
  });
22884
+ const contextCache = new Map();
22852
22885
  const server = await startServer({
22853
22886
  signal,
22854
22887
  stopOnExit: false,
@@ -22877,6 +22910,7 @@ const startDevServer = async ({
22877
22910
  logLevel,
22878
22911
  serverStopCallbacks,
22879
22912
  serverEventsDispatcher,
22913
+ contextCache,
22880
22914
  rootDirectoryUrl,
22881
22915
  runtimeCompat,
22882
22916
  plugins,
@@ -22967,7 +23001,8 @@ const startDevServer = async ({
22967
23001
  origin: server.origin,
22968
23002
  stop: () => {
22969
23003
  server.stop();
22970
- }
23004
+ },
23005
+ contextCache
22971
23006
  };
22972
23007
  };
22973
23008
 
@@ -23965,7 +24000,7 @@ const descriptionFormatters = {
23965
24000
  }) => {
23966
24001
  return ANSI.color(`${UNICODE.FAILURE_RAW} execution ${index + 1} of ${total} timeout after ${executionParams.allocatedMs}ms`, EXECUTION_COLORS.timedout);
23967
24002
  },
23968
- efailedrrored: ({
24003
+ failed: ({
23969
24004
  index,
23970
24005
  total
23971
24006
  }) => {
@@ -26153,30 +26188,46 @@ const startBuildServer = async ({
26153
26188
  },
26154
26189
  buildServerAutoreload = false,
26155
26190
  buildServerMainFile = getCallerPosition().url,
26156
- cooldownBetweenFileEvents
26191
+ cooldownBetweenFileEvents,
26192
+ ...rest
26157
26193
  }) => {
26158
- const logger = createLogger({
26159
- logLevel
26160
- });
26161
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl);
26162
- buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl);
26163
- if (buildIndexPath) {
26164
- if (typeof buildIndexPath !== "string") {
26165
- throw new TypeError(`buildIndexPath must be a string, got ${buildIndexPath}`);
26194
+ // params validation
26195
+ {
26196
+ const unexpectedParamNames = Object.keys(rest);
26197
+ if (unexpectedParamNames.length > 0) {
26198
+ throw new TypeError(`${unexpectedParamNames.join(",")}: there is no such param`);
26166
26199
  }
26167
- if (buildIndexPath[0] === "/") {
26168
- buildIndexPath = buildIndexPath.slice(1);
26169
- } else {
26170
- const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href;
26171
- if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
26172
- throw new Error(`buildIndexPath must be relative, got ${buildIndexPath}`);
26173
- }
26174
- buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length);
26200
+ const rootDirectoryUrlValidation = validateDirectoryUrl(rootDirectoryUrl);
26201
+ if (!rootDirectoryUrlValidation.valid) {
26202
+ throw new TypeError(`rootDirectoryUrl ${rootDirectoryUrlValidation.message}, got ${rootDirectoryUrl}`);
26175
26203
  }
26176
- if (!existsSync(new URL(buildIndexPath, buildDirectoryUrl))) {
26177
- buildIndexPath = null;
26204
+ rootDirectoryUrl = rootDirectoryUrlValidation.value;
26205
+ const buildDirectoryUrlValidation = validateDirectoryUrl(buildDirectoryUrl);
26206
+ if (!buildDirectoryUrlValidation.valid) {
26207
+ throw new TypeError(`buildDirectoryUrl ${buildDirectoryUrlValidation.message}, got ${buildDirectoryUrlValidation}`);
26208
+ }
26209
+ buildDirectoryUrl = buildDirectoryUrlValidation.value;
26210
+ if (buildIndexPath) {
26211
+ if (typeof buildIndexPath !== "string") {
26212
+ throw new TypeError(`buildIndexPath must be a string, got ${buildIndexPath}`);
26213
+ }
26214
+ if (buildIndexPath[0] === "/") {
26215
+ buildIndexPath = buildIndexPath.slice(1);
26216
+ } else {
26217
+ const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href;
26218
+ if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
26219
+ throw new Error(`buildIndexPath must be relative, got ${buildIndexPath}`);
26220
+ }
26221
+ buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length);
26222
+ }
26223
+ if (!existsSync(new URL(buildIndexPath, buildDirectoryUrl))) {
26224
+ buildIndexPath = null;
26225
+ }
26178
26226
  }
26179
26227
  }
26228
+ const logger = createLogger({
26229
+ logLevel
26230
+ });
26180
26231
  const operation = Abort.startOperation();
26181
26232
  operation.addAbortSignal(signal);
26182
26233
  if (handleSIGINT) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "31.0.0",
3
+ "version": "31.1.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -75,6 +75,7 @@
75
75
  "@jsenv/log": "3.3.4",
76
76
  "@jsenv/node-esm-resolution": "1.0.1",
77
77
  "@jsenv/plugin-bundling": "2.0.0",
78
+ "@jsenv/plugin-globals": "1.1.0",
78
79
  "@jsenv/server": "15.0.0",
79
80
  "@jsenv/sourcemap": "1.0.9",
80
81
  "@jsenv/uneval": "1.6.0",
@@ -113,6 +114,6 @@
113
114
  "eslint-plugin-import": "2.27.5",
114
115
  "eslint-plugin-react": "7.32.2",
115
116
  "playwright": "1.31.2",
116
- "prettier": "2.8.4"
117
+ "prettier": "2.8.6"
117
118
  }
118
119
  }
@@ -23,7 +23,7 @@ import {
23
23
  jsenvServiceErrorHandler,
24
24
  } from "@jsenv/server"
25
25
  import {
26
- assertAndNormalizeDirectoryUrl,
26
+ validateDirectoryUrl,
27
27
  registerDirectoryLifecycle,
28
28
  } from "@jsenv/filesystem"
29
29
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
@@ -62,32 +62,55 @@ export const startBuildServer = async ({
62
62
  buildServerAutoreload = false,
63
63
  buildServerMainFile = getCallerPosition().url,
64
64
  cooldownBetweenFileEvents,
65
+ ...rest
65
66
  }) => {
66
- const logger = createLogger({ logLevel })
67
- rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
68
- buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
69
- if (buildIndexPath) {
70
- if (typeof buildIndexPath !== "string") {
67
+ // params validation
68
+ {
69
+ const unexpectedParamNames = Object.keys(rest)
70
+ if (unexpectedParamNames.length > 0) {
71
+ throw new TypeError(
72
+ `${unexpectedParamNames.join(",")}: there is no such param`,
73
+ )
74
+ }
75
+ const rootDirectoryUrlValidation = validateDirectoryUrl(rootDirectoryUrl)
76
+ if (!rootDirectoryUrlValidation.valid) {
77
+ throw new TypeError(
78
+ `rootDirectoryUrl ${rootDirectoryUrlValidation.message}, got ${rootDirectoryUrl}`,
79
+ )
80
+ }
81
+ rootDirectoryUrl = rootDirectoryUrlValidation.value
82
+ const buildDirectoryUrlValidation = validateDirectoryUrl(buildDirectoryUrl)
83
+ if (!buildDirectoryUrlValidation.valid) {
71
84
  throw new TypeError(
72
- `buildIndexPath must be a string, got ${buildIndexPath}`,
85
+ `buildDirectoryUrl ${buildDirectoryUrlValidation.message}, got ${buildDirectoryUrlValidation}`,
73
86
  )
74
87
  }
75
- if (buildIndexPath[0] === "/") {
76
- buildIndexPath = buildIndexPath.slice(1)
77
- } else {
78
- const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href
79
- if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
80
- throw new Error(
81
- `buildIndexPath must be relative, got ${buildIndexPath}`,
88
+ buildDirectoryUrl = buildDirectoryUrlValidation.value
89
+
90
+ if (buildIndexPath) {
91
+ if (typeof buildIndexPath !== "string") {
92
+ throw new TypeError(
93
+ `buildIndexPath must be a string, got ${buildIndexPath}`,
82
94
  )
83
95
  }
84
- buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length)
85
- }
86
- if (!existsSync(new URL(buildIndexPath, buildDirectoryUrl))) {
87
- buildIndexPath = null
96
+ if (buildIndexPath[0] === "/") {
97
+ buildIndexPath = buildIndexPath.slice(1)
98
+ } else {
99
+ const buildIndexUrl = new URL(buildIndexPath, buildDirectoryUrl).href
100
+ if (!buildIndexUrl.startsWith(buildDirectoryUrl)) {
101
+ throw new Error(
102
+ `buildIndexPath must be relative, got ${buildIndexPath}`,
103
+ )
104
+ }
105
+ buildIndexPath = buildIndexUrl.slice(buildDirectoryUrl.length)
106
+ }
107
+ if (!existsSync(new URL(buildIndexPath, buildDirectoryUrl))) {
108
+ buildIndexPath = null
109
+ }
88
110
  }
89
111
  }
90
112
 
113
+ const logger = createLogger({ logLevel })
91
114
  const operation = Abort.startOperation()
92
115
  operation.addAbortSignal(signal)
93
116
  if (handleSIGINT) {
@@ -20,6 +20,7 @@ export const createFileService = ({
20
20
  logLevel,
21
21
  serverStopCallbacks,
22
22
  serverEventsDispatcher,
23
+ contextCache,
23
24
 
24
25
  rootDirectoryUrl,
25
26
  runtimeCompat,
@@ -82,7 +83,6 @@ export const createFileService = ({
82
83
  })
83
84
  serverStopCallbacks.push(stopWatchingClientFiles)
84
85
 
85
- const contextCache = new Map()
86
86
  const getOrCreateContext = (request) => {
87
87
  const { runtimeName, runtimeVersion } = parseUserAgentHeader(
88
88
  request.headers["user-agent"],
@@ -150,6 +150,7 @@ export const createFileService = ({
150
150
  ribbon,
151
151
  }),
152
152
  ],
153
+ supervisor,
153
154
  minification: false,
154
155
  sourcemaps,
155
156
  sourcemapsSourcesProtocol,
@@ -173,6 +173,7 @@ export const startDevServer = async ({
173
173
  serverStopCallbacks.push(() => {
174
174
  serverEventsDispatcher.destroy()
175
175
  })
176
+ const contextCache = new Map()
176
177
  const server = await startServer({
177
178
  signal,
178
179
  stopOnExit: false,
@@ -208,6 +209,7 @@ export const startDevServer = async ({
208
209
  logLevel,
209
210
  serverStopCallbacks,
210
211
  serverEventsDispatcher,
212
+ contextCache,
211
213
 
212
214
  rootDirectoryUrl,
213
215
  runtimeCompat,
@@ -304,5 +306,6 @@ export const startDevServer = async ({
304
306
  stop: () => {
305
307
  server.stop()
306
308
  },
309
+ contextCache,
307
310
  }
308
311
  }
@@ -673,7 +673,17 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
673
673
  // (error hapenning before urlInfo.content can be set, or 404 for instance)
674
674
  // in that case we can't write anything
675
675
  } else {
676
- writeFileSync(new URL(generatedUrl), urlInfo.content)
676
+ let contentIsInlined = urlInfo.isInline
677
+ if (
678
+ contentIsInlined &&
679
+ context.supervisor &&
680
+ urlGraph.getUrlInfo(urlInfo.inlineUrlSite.url).type === "html"
681
+ ) {
682
+ contentIsInlined = false
683
+ }
684
+ if (!contentIsInlined) {
685
+ writeFileSync(new URL(generatedUrl), urlInfo.content)
686
+ }
677
687
  const { sourcemapGeneratedUrl, sourcemap } = urlInfo
678
688
  if (sourcemapGeneratedUrl && sourcemap) {
679
689
  writeFileSync(
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Source code can contain the following
3
+ * - __dev__
4
+ * - __build__
5
+ * A global will be injected with true/false when needed
6
+ */
7
+
8
+ import { replacePlaceholders } from "@jsenv/plugin-placeholders"
9
+
10
+ export const jsenvPluginGlobalScenarios = () => {
11
+ const transformIfNeeded = (urlInfo, context) => {
12
+ return replacePlaceholders(urlInfo, {
13
+ __DEV__: context.dev,
14
+ __BUILD__: context.build,
15
+ })
16
+ }
17
+
18
+ return {
19
+ name: "jsenv:global_scenario",
20
+ appliesDuring: "*",
21
+ transformUrlContent: {
22
+ js_classic: transformIfNeeded,
23
+ js_module: transformIfNeeded,
24
+ html: transformIfNeeded,
25
+ },
26
+ }
27
+ }
@@ -8,6 +8,7 @@ import { jsenvPluginInline } from "./inline/jsenv_plugin_inline.js"
8
8
  import { jsenvPluginSupervisor } from "./supervisor/jsenv_plugin_supervisor.js"
9
9
  import { jsenvPluginCommonJsGlobals } from "./commonjs_globals/jsenv_plugin_commonjs_globals.js"
10
10
  import { jsenvPluginImportMetaScenarios } from "./import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js"
11
+ import { jsenvPluginGlobalScenarios } from "./global_scenarios/jsenv_plugin_global_scenarios.js"
11
12
  import { jsenvPluginTranspilation } from "./transpilation/jsenv_plugin_transpilation.js"
12
13
  import { jsenvPluginNodeRuntime } from "./node_runtime/jsenv_plugin_node_runtime.js"
13
14
  // autoreload
@@ -89,6 +90,7 @@ export const getCorePlugins = ({
89
90
  jsenvPluginUrlVersion(),
90
91
  jsenvPluginCommonJsGlobals(),
91
92
  jsenvPluginImportMetaScenarios(),
93
+ jsenvPluginGlobalScenarios(),
92
94
 
93
95
  jsenvPluginNodeRuntime({ runtimeCompat }),
94
96
 
@@ -221,7 +221,7 @@ const descriptionFormatters = {
221
221
  EXECUTION_COLORS.timedout,
222
222
  )
223
223
  },
224
- efailedrrored: ({ index, total }) => {
224
+ failed: ({ index, total }) => {
225
225
  return ANSI.color(
226
226
  `${UNICODE.FAILURE_RAW} execution ${index + 1} of ${total} failed`,
227
227
  EXECUTION_COLORS.failed,