@jsenv/core 40.12.13 → 41.0.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/build/build.js +267 -469
- package/dist/client/import_meta_css/import_meta_css_build.js +41 -12
- package/dist/client/import_meta_css/import_meta_css_dev.js +43 -31
- package/dist/start_build_server/start_build_server.js +7 -7
- package/dist/start_dev_server/start_dev_server.js +255 -448
- package/package.json +2 -2
- package/src/build/build.js +16 -15
- package/src/build/build_specifier_manager.js +11 -10
- package/src/build/mappings_injection.js +12 -11
- package/src/build/start_build_server.js +9 -9
- package/src/dev/start_dev_server.js +26 -26
- package/src/kitchen/errors.js +11 -11
- package/src/kitchen/kitchen.js +29 -21
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +1 -1
- package/src/plugins/autoreload_on_server_restart/jsenv_plugin_autoreload_on_server_restart.js +1 -1
- package/src/plugins/chrome_devtools_json/jsenv_plugin_chrome_devtools_json.js +1 -1
- package/src/plugins/import_meta_css/client/import_meta_css_build.js +41 -12
- package/src/plugins/import_meta_css/client/import_meta_css_dev.js +43 -31
- package/src/plugins/import_meta_css/jsenv_plugin_import_meta_css.js +78 -17
- package/src/plugins/jsenv_plugins_controller.js +197 -0
- package/src/plugins/protocol_file/jsenv_plugin_directory_listing.js +1 -1
- package/src/plugins/server_events/jsenv_plugin_server_events.js +1 -1
- package/src/plugins/plugin_controller.js +0 -458
|
@@ -1,20 +1,49 @@
|
|
|
1
1
|
export const installImportMetaCssBuild = (importMeta) => {
|
|
2
|
-
const
|
|
2
|
+
const IMPORT_META_CSS_BUILD = "jsenv_import_meta_css_build";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
if (importMeta.css === IMPORT_META_CSS_BUILD) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const stylesheetMap = new Map();
|
|
9
|
+
const adopt = (url, value) => {
|
|
10
|
+
const stylesheet = new CSSStyleSheet({ baseUrl: importMeta.url });
|
|
11
|
+
stylesheet.replaceSync(value);
|
|
12
|
+
stylesheetMap.set(url, stylesheet);
|
|
13
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
|
|
14
|
+
};
|
|
15
|
+
const update = (url, value) => {
|
|
16
|
+
stylesheetMap.get(url).replaceSync(value);
|
|
17
|
+
};
|
|
18
|
+
const remove = (url) => {
|
|
19
|
+
const stylesheet = stylesheetMap.get(url);
|
|
20
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
21
|
+
(s) => s !== stylesheet,
|
|
22
|
+
);
|
|
23
|
+
stylesheetMap.delete(url);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const currentCssSourceMap = new Map();
|
|
6
27
|
Object.defineProperty(importMeta, "css", {
|
|
7
28
|
configurable: true,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
29
|
+
get() {
|
|
30
|
+
return IMPORT_META_CSS_BUILD;
|
|
31
|
+
},
|
|
32
|
+
set([value, url]) {
|
|
33
|
+
if (value === undefined) {
|
|
34
|
+
if (stylesheetMap.has(url)) {
|
|
35
|
+
remove(url);
|
|
36
|
+
currentCssSourceMap.delete(url);
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!stylesheetMap.has(url)) {
|
|
41
|
+
adopt(url, value);
|
|
42
|
+
currentCssSourceMap.set(url, value);
|
|
43
|
+
} else if (currentCssSourceMap.get(url) !== value) {
|
|
44
|
+
update(url, value);
|
|
45
|
+
currentCssSourceMap.set(url, value);
|
|
11
46
|
}
|
|
12
|
-
called = true;
|
|
13
|
-
stylesheet.replaceSync(value);
|
|
14
|
-
document.adoptedStyleSheets = [
|
|
15
|
-
...document.adoptedStyleSheets,
|
|
16
|
-
stylesheet,
|
|
17
|
-
];
|
|
18
47
|
},
|
|
19
48
|
});
|
|
20
49
|
};
|
|
@@ -1,46 +1,58 @@
|
|
|
1
1
|
export const installImportMetaCssDev = (importMeta) => {
|
|
2
|
-
|
|
3
|
-
let stylesheet = new CSSStyleSheet({ baseUrl: importMeta.url });
|
|
4
|
-
let adopted = false;
|
|
2
|
+
const IMPORT_META_CSS_DEV = "jsenv_import_meta_css_dev";
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
cssText += `
|
|
4
|
+
// useless today but browser might catch up to display it in devtools
|
|
5
|
+
const addUrlInfo = (cssText) => {
|
|
6
|
+
let cssTextWithUrlInfo = cssText;
|
|
7
|
+
cssTextWithUrlInfo += `
|
|
11
8
|
/* sourceURL=${importMeta.url} */
|
|
12
9
|
/* inlined from ${importMeta.url} */`;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
adopted = false;
|
|
30
|
-
}
|
|
31
|
-
},
|
|
10
|
+
return cssTextWithUrlInfo;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let stylesheet;
|
|
14
|
+
const adopt = (value) => {
|
|
15
|
+
stylesheet = new CSSStyleSheet({ baseUrl: importMeta.url });
|
|
16
|
+
stylesheet.replaceSync(addUrlInfo(value));
|
|
17
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
|
|
18
|
+
};
|
|
19
|
+
const update = (value) => {
|
|
20
|
+
stylesheet.replaceSync(addUrlInfo(value));
|
|
21
|
+
};
|
|
22
|
+
const remove = () => {
|
|
23
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
24
|
+
(s) => s !== stylesheet,
|
|
25
|
+
);
|
|
32
26
|
};
|
|
33
27
|
|
|
28
|
+
let currentCssSource;
|
|
34
29
|
Object.defineProperty(importMeta, "css", {
|
|
35
30
|
configurable: true,
|
|
36
31
|
get() {
|
|
37
|
-
return
|
|
32
|
+
return IMPORT_META_CSS_DEV;
|
|
38
33
|
},
|
|
39
34
|
set(value) {
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
if (stylesheet) {
|
|
37
|
+
remove();
|
|
38
|
+
stylesheet = undefined;
|
|
39
|
+
currentCssSource = undefined;
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!stylesheet) {
|
|
44
|
+
adopt(value);
|
|
45
|
+
currentCssSource = value;
|
|
46
|
+
} else if (currentCssSource !== value) {
|
|
47
|
+
update(value);
|
|
48
|
+
currentCssSource = value;
|
|
49
|
+
}
|
|
42
50
|
},
|
|
43
51
|
});
|
|
44
52
|
|
|
45
|
-
return
|
|
53
|
+
return () => {
|
|
54
|
+
remove();
|
|
55
|
+
stylesheet = undefined;
|
|
56
|
+
currentCssSource = undefined;
|
|
57
|
+
};
|
|
46
58
|
};
|
|
@@ -36,11 +36,7 @@ export const jsenvPluginImportMetaCss = () => {
|
|
|
36
36
|
appliesDuring: "*",
|
|
37
37
|
transformUrlContent: {
|
|
38
38
|
js_module: async (urlInfo) => {
|
|
39
|
-
if (
|
|
40
|
-
!urlInfo.content.includes("import.meta.css") ||
|
|
41
|
-
// there is already our installImportMetaCssBuild in the file
|
|
42
|
-
urlInfo.content.includes("installImportMetaCssBuild")
|
|
43
|
-
) {
|
|
39
|
+
if (!urlInfo.content.includes("import.meta.css")) {
|
|
44
40
|
return null;
|
|
45
41
|
}
|
|
46
42
|
const { metadata } = await applyBabelPlugins({
|
|
@@ -54,22 +50,78 @@ export const jsenvPluginImportMetaCss = () => {
|
|
|
54
50
|
if (!usesImportMetaCss) {
|
|
55
51
|
return null;
|
|
56
52
|
}
|
|
53
|
+
if (urlInfo.context.build) {
|
|
54
|
+
const rootDirectoryUrl = urlInfo.context.rootDirectoryUrl;
|
|
55
|
+
const relativeUrl = urlInfo.originalUrl.slice(
|
|
56
|
+
rootDirectoryUrl.length - 1,
|
|
57
|
+
);
|
|
58
|
+
const { code } = await applyBabelPlugins({
|
|
59
|
+
babelPlugins: [
|
|
60
|
+
[babelPluginRewriteImportMetaCssAssignment, { relativeUrl }],
|
|
61
|
+
],
|
|
62
|
+
input: urlInfo.content,
|
|
63
|
+
inputIsJsModule: true,
|
|
64
|
+
inputUrl: urlInfo.originalUrl,
|
|
65
|
+
outputUrl: urlInfo.generatedUrl,
|
|
66
|
+
});
|
|
67
|
+
if (code === urlInfo.content) {
|
|
68
|
+
// all assignments were already in array form (pre-built file) — nothing to do
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return injectImportMetaCss(urlInfo, {
|
|
72
|
+
content: code,
|
|
73
|
+
importFrom: importMetaCssBuildClientFileUrl,
|
|
74
|
+
importName: "installImportMetaCssBuild",
|
|
75
|
+
importAs: "__installImportMetaCssBuild__",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
57
78
|
return injectImportMetaCss(urlInfo, {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
: "installImportMetaCssDev",
|
|
64
|
-
importAs: urlInfo.context.build
|
|
65
|
-
? "__installImportMetaCssBuild__"
|
|
66
|
-
: "__installImportMetaCssDev__",
|
|
79
|
+
content: urlInfo.content,
|
|
80
|
+
importFrom: importMetaCssDevClientFileUrl,
|
|
81
|
+
importName: "installImportMetaCssDev",
|
|
82
|
+
importAs: "__installImportMetaCssDev__",
|
|
83
|
+
hot: true,
|
|
67
84
|
});
|
|
68
85
|
},
|
|
69
86
|
},
|
|
70
87
|
};
|
|
71
88
|
};
|
|
72
89
|
|
|
90
|
+
const babelPluginRewriteImportMetaCssAssignment = (
|
|
91
|
+
{ types: t },
|
|
92
|
+
{ relativeUrl },
|
|
93
|
+
) => {
|
|
94
|
+
return {
|
|
95
|
+
name: "rewrite-import-meta-css-assignment",
|
|
96
|
+
visitor: {
|
|
97
|
+
AssignmentExpression(path) {
|
|
98
|
+
const { left, right } = path.node;
|
|
99
|
+
if (left.type !== "MemberExpression") {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const { object, property } = left;
|
|
103
|
+
if (object.type !== "MetaProperty") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (object.meta.name !== "import" || object.property.name !== "meta") {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (property.name !== "css") {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// already transformed (e.g. pre-built file): leave as-is
|
|
113
|
+
if (right.type === "ArrayExpression") {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
path.node.right = t.arrayExpression([
|
|
117
|
+
right,
|
|
118
|
+
t.stringLiteral(relativeUrl),
|
|
119
|
+
]);
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
|
|
73
125
|
const babelPluginMetadataUsesImportMetaCss = () => {
|
|
74
126
|
return {
|
|
75
127
|
name: "metadata-uses-import-meta-css",
|
|
@@ -101,7 +153,10 @@ const babelPluginMetadataUsesImportMetaCss = () => {
|
|
|
101
153
|
};
|
|
102
154
|
};
|
|
103
155
|
|
|
104
|
-
const injectImportMetaCss = (
|
|
156
|
+
const injectImportMetaCss = (
|
|
157
|
+
urlInfo,
|
|
158
|
+
{ content, importFrom, importName, importAs, hot },
|
|
159
|
+
) => {
|
|
105
160
|
const importMetaCssClientFileReference = urlInfo.dependencies.inject({
|
|
106
161
|
parentUrl: urlInfo.url,
|
|
107
162
|
type: "js_import",
|
|
@@ -117,7 +172,9 @@ const injectImportMetaCss = (urlInfo, { importFrom, importName, importAs }) => {
|
|
|
117
172
|
importBeforeFrom = `{ ${importName} } }`;
|
|
118
173
|
importVariableName = importName;
|
|
119
174
|
}
|
|
120
|
-
|
|
175
|
+
|
|
176
|
+
const prelude = hot
|
|
177
|
+
? `import ${importBeforeFrom} from ${importMetaCssClientFileReference.generatedSpecifier};
|
|
121
178
|
|
|
122
179
|
const remove = ${importVariableName}(import.meta);
|
|
123
180
|
if (import.meta.hot) {
|
|
@@ -126,9 +183,13 @@ if (import.meta.hot) {
|
|
|
126
183
|
});
|
|
127
184
|
}
|
|
128
185
|
|
|
186
|
+
`
|
|
187
|
+
: `import ${importBeforeFrom} from ${importMetaCssClientFileReference.generatedSpecifier};
|
|
188
|
+
|
|
189
|
+
${importVariableName}(import.meta);
|
|
190
|
+
|
|
129
191
|
`;
|
|
130
192
|
|
|
131
|
-
let content = urlInfo.content;
|
|
132
193
|
return {
|
|
133
194
|
content: `${prelude.replace(/\n/g, "")}${content}`,
|
|
134
195
|
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { createPluginsController } from "@jsenv/server/src/plugins_controller.js";
|
|
2
|
+
|
|
3
|
+
import { jsenvPluginHtmlSyntaxErrorFallback } from "./html_syntax_error_fallback/jsenv_plugin_html_syntax_error_fallback.js";
|
|
4
|
+
|
|
5
|
+
export const createJsenvPluginStore = async (plugins) => {
|
|
6
|
+
const allServerRoutes = [];
|
|
7
|
+
const allServerPlugins = [];
|
|
8
|
+
const pluginArray = [];
|
|
9
|
+
|
|
10
|
+
const pluginPromises = [];
|
|
11
|
+
const addPlugin = async (plugin) => {
|
|
12
|
+
if (plugin && typeof plugin.then === "function") {
|
|
13
|
+
pluginPromises.push(plugin);
|
|
14
|
+
const value = await plugin;
|
|
15
|
+
addPlugin(value);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(plugin)) {
|
|
19
|
+
for (const subplugin of plugin) {
|
|
20
|
+
addPlugin(subplugin);
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (plugin === null || typeof plugin !== "object") {
|
|
25
|
+
throw new TypeError(`plugin must be objects, got ${plugin}`);
|
|
26
|
+
}
|
|
27
|
+
if (!plugin.name) {
|
|
28
|
+
plugin.name = "anonymous";
|
|
29
|
+
}
|
|
30
|
+
const { serverRoutes } = plugin;
|
|
31
|
+
if (serverRoutes) {
|
|
32
|
+
for (const serverRoute of serverRoutes) {
|
|
33
|
+
allServerRoutes.push(serverRoute);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const { serverPlugins } = plugin;
|
|
37
|
+
if (serverPlugins) {
|
|
38
|
+
const serverPlugins = plugin.serverPlugins;
|
|
39
|
+
for (const serverPlugin of serverPlugins) {
|
|
40
|
+
allServerPlugins.push(serverPlugin);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
pluginArray.push(plugin);
|
|
44
|
+
};
|
|
45
|
+
addPlugin(jsenvPluginHtmlSyntaxErrorFallback());
|
|
46
|
+
for (const plugin of plugins) {
|
|
47
|
+
addPlugin(plugin);
|
|
48
|
+
}
|
|
49
|
+
await Promise.all(pluginPromises);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
pluginArray,
|
|
53
|
+
allServerRoutes,
|
|
54
|
+
allServerPlugins,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const createJsenvPluginsController = async (
|
|
59
|
+
pluginStore,
|
|
60
|
+
kitchen,
|
|
61
|
+
{ meta } = {},
|
|
62
|
+
) => {
|
|
63
|
+
kitchen.context.getPluginMeta = (id) => pluginsController.getPluginMeta(id);
|
|
64
|
+
const pluginsController = await createPluginsController({
|
|
65
|
+
plugins: pluginStore.pluginArray,
|
|
66
|
+
pluginDescription: JSENV_PLUGIN_DESCRIPTION,
|
|
67
|
+
filterPlugin: (plugin) => testAppliesDuring(plugin, kitchen),
|
|
68
|
+
getInitPluginArgs: (plugin) => [kitchen.context, { plugin }],
|
|
69
|
+
getEffectArgs: ({ otherPlugins }) => [
|
|
70
|
+
{ kitchenContext: kitchen.context, otherPlugins },
|
|
71
|
+
],
|
|
72
|
+
meta,
|
|
73
|
+
});
|
|
74
|
+
return pluginsController;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const hook = { type: "hook" };
|
|
78
|
+
const nonHook = {};
|
|
79
|
+
|
|
80
|
+
const assertUrlReturnValue = (valueReturned, urlInfo, { hook }) => {
|
|
81
|
+
if (valueReturned instanceof URL) {
|
|
82
|
+
return valueReturned.href;
|
|
83
|
+
}
|
|
84
|
+
if (typeof valueReturned === "string") {
|
|
85
|
+
return valueReturned;
|
|
86
|
+
}
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Unexpected value returned by hook "${hook.plugin.name}.${hook.name}()": it must be a string; got ${valueReturned}`,
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
const assertContentReturnValue = (valueReturned, urlInfo, { hook }) => {
|
|
92
|
+
if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
|
|
93
|
+
return { content: valueReturned };
|
|
94
|
+
}
|
|
95
|
+
if (typeof valueReturned === "object") {
|
|
96
|
+
const { content, body } = valueReturned;
|
|
97
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
98
|
+
return valueReturned;
|
|
99
|
+
}
|
|
100
|
+
if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
|
|
101
|
+
if (Object.hasOwn(valueReturned, "contentInjections")) {
|
|
102
|
+
return valueReturned;
|
|
103
|
+
}
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Unexpected "content" returned by hook "${hook.plugin.name}.${hook.name}()": it must be a string or a buffer; got ${content}`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return valueReturned;
|
|
109
|
+
}
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Unexpected value returned by hook "${hook.plugin.name}.${hook.name}()": it must be a string, a buffer or an object; got ${valueReturned}`,
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const JSENV_PLUGIN_DESCRIPTION = {
|
|
116
|
+
name: "jsenv plugin",
|
|
117
|
+
properties: {
|
|
118
|
+
// non-hook properties (silently skipped)
|
|
119
|
+
appliesDuring: nonHook,
|
|
120
|
+
serverEvents: nonHook,
|
|
121
|
+
mustStayFirst: nonHook,
|
|
122
|
+
serverRoutes: nonHook,
|
|
123
|
+
serverPlugins: nonHook,
|
|
124
|
+
// hooks
|
|
125
|
+
init: hook,
|
|
126
|
+
resolveReference: {
|
|
127
|
+
type: "hook",
|
|
128
|
+
assertAndNormalize: assertUrlReturnValue,
|
|
129
|
+
},
|
|
130
|
+
redirectReference: {
|
|
131
|
+
type: "hook",
|
|
132
|
+
assertAndNormalize: assertUrlReturnValue,
|
|
133
|
+
},
|
|
134
|
+
transformReferenceSearchParams: hook,
|
|
135
|
+
formatReference: hook,
|
|
136
|
+
urlInfoCreated: hook,
|
|
137
|
+
fetchUrlContent: {
|
|
138
|
+
type: "hook",
|
|
139
|
+
assertAndNormalize: assertContentReturnValue,
|
|
140
|
+
},
|
|
141
|
+
transformUrlContent: {
|
|
142
|
+
type: "hook",
|
|
143
|
+
assertAndNormalize: assertContentReturnValue,
|
|
144
|
+
},
|
|
145
|
+
finalizeUrlContent: {
|
|
146
|
+
type: "hook",
|
|
147
|
+
assertAndNormalize: assertContentReturnValue,
|
|
148
|
+
},
|
|
149
|
+
bundle: hook,
|
|
150
|
+
optimizeBuildUrlContent: {
|
|
151
|
+
type: "hook",
|
|
152
|
+
assertAndNormalize: assertContentReturnValue,
|
|
153
|
+
},
|
|
154
|
+
cooked: hook,
|
|
155
|
+
augmentResponse: hook,
|
|
156
|
+
destroy: hook,
|
|
157
|
+
effect: hook,
|
|
158
|
+
refineBuildUrlContent: hook,
|
|
159
|
+
refineBuild: hook,
|
|
160
|
+
// serverRoutes and serverPlugins are nonHook above
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const testAppliesDuring = (plugin, kitchen) => {
|
|
165
|
+
const { appliesDuring } = plugin;
|
|
166
|
+
if (appliesDuring === undefined) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
if (appliesDuring === "*") {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
if (typeof appliesDuring === "string") {
|
|
173
|
+
if (appliesDuring !== "dev" && appliesDuring !== "build") {
|
|
174
|
+
throw new TypeError(
|
|
175
|
+
`"appliesDuring" must be "dev" or "build", got ${appliesDuring}`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
if (kitchen.context[appliesDuring]) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
if (typeof appliesDuring === "object") {
|
|
184
|
+
for (const key of Object.keys(appliesDuring)) {
|
|
185
|
+
if (!appliesDuring[key] && kitchen.context[key]) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (appliesDuring[key] && kitchen.context[key]) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
throw new TypeError(
|
|
195
|
+
`"appliesDuring" must be an object or a string, got ${appliesDuring}`,
|
|
196
|
+
);
|
|
197
|
+
};
|
|
@@ -90,7 +90,7 @@ export const jsenvPluginServerEvents = ({ clientAutoreload }) => {
|
|
|
90
90
|
return stringifyHtmlAst(htmlAst);
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
|
-
|
|
93
|
+
serverRoutes: [
|
|
94
94
|
{
|
|
95
95
|
endpoint: "GET /.internal/events.websocket",
|
|
96
96
|
description: `Jsenv dev server emit server events on this endpoint. When a file is saved the "reload" event is sent here.`,
|