@jsenv/core 40.12.13 → 40.12.14
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 +259 -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 +247 -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 +70 -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,70 @@ 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
|
+
return injectImportMetaCss(urlInfo, {
|
|
68
|
+
content: code,
|
|
69
|
+
importFrom: importMetaCssBuildClientFileUrl,
|
|
70
|
+
importName: "installImportMetaCssBuild",
|
|
71
|
+
importAs: "__installImportMetaCssBuild__",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
57
74
|
return injectImportMetaCss(urlInfo, {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
: "installImportMetaCssDev",
|
|
64
|
-
importAs: urlInfo.context.build
|
|
65
|
-
? "__installImportMetaCssBuild__"
|
|
66
|
-
: "__installImportMetaCssDev__",
|
|
75
|
+
content: urlInfo.content,
|
|
76
|
+
importFrom: importMetaCssDevClientFileUrl,
|
|
77
|
+
importName: "installImportMetaCssDev",
|
|
78
|
+
importAs: "__installImportMetaCssDev__",
|
|
79
|
+
hot: true,
|
|
67
80
|
});
|
|
68
81
|
},
|
|
69
82
|
},
|
|
70
83
|
};
|
|
71
84
|
};
|
|
72
85
|
|
|
86
|
+
const babelPluginRewriteImportMetaCssAssignment = (
|
|
87
|
+
{ types: t },
|
|
88
|
+
{ relativeUrl },
|
|
89
|
+
) => {
|
|
90
|
+
return {
|
|
91
|
+
name: "rewrite-import-meta-css-assignment",
|
|
92
|
+
visitor: {
|
|
93
|
+
AssignmentExpression(path) {
|
|
94
|
+
const { left, right } = path.node;
|
|
95
|
+
if (left.type !== "MemberExpression") {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const { object, property } = left;
|
|
99
|
+
if (object.type !== "MetaProperty") {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (object.meta.name !== "import" || object.property.name !== "meta") {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (property.name !== "css") {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
path.node.right = t.arrayExpression([
|
|
109
|
+
right,
|
|
110
|
+
t.stringLiteral(relativeUrl),
|
|
111
|
+
]);
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
73
117
|
const babelPluginMetadataUsesImportMetaCss = () => {
|
|
74
118
|
return {
|
|
75
119
|
name: "metadata-uses-import-meta-css",
|
|
@@ -101,7 +145,10 @@ const babelPluginMetadataUsesImportMetaCss = () => {
|
|
|
101
145
|
};
|
|
102
146
|
};
|
|
103
147
|
|
|
104
|
-
const injectImportMetaCss = (
|
|
148
|
+
const injectImportMetaCss = (
|
|
149
|
+
urlInfo,
|
|
150
|
+
{ content, importFrom, importName, importAs, hot },
|
|
151
|
+
) => {
|
|
105
152
|
const importMetaCssClientFileReference = urlInfo.dependencies.inject({
|
|
106
153
|
parentUrl: urlInfo.url,
|
|
107
154
|
type: "js_import",
|
|
@@ -117,7 +164,9 @@ const injectImportMetaCss = (urlInfo, { importFrom, importName, importAs }) => {
|
|
|
117
164
|
importBeforeFrom = `{ ${importName} } }`;
|
|
118
165
|
importVariableName = importName;
|
|
119
166
|
}
|
|
120
|
-
|
|
167
|
+
|
|
168
|
+
const prelude = hot
|
|
169
|
+
? `import ${importBeforeFrom} from ${importMetaCssClientFileReference.generatedSpecifier};
|
|
121
170
|
|
|
122
171
|
const remove = ${importVariableName}(import.meta);
|
|
123
172
|
if (import.meta.hot) {
|
|
@@ -126,9 +175,13 @@ if (import.meta.hot) {
|
|
|
126
175
|
});
|
|
127
176
|
}
|
|
128
177
|
|
|
178
|
+
`
|
|
179
|
+
: `import ${importBeforeFrom} from ${importMetaCssClientFileReference.generatedSpecifier};
|
|
180
|
+
|
|
181
|
+
${importVariableName}(import.meta);
|
|
182
|
+
|
|
129
183
|
`;
|
|
130
184
|
|
|
131
|
-
let content = urlInfo.content;
|
|
132
185
|
return {
|
|
133
186
|
content: `${prelude.replace(/\n/g, "")}${content}`,
|
|
134
187
|
};
|
|
@@ -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.`,
|