flecks/packages/server/build/runtime.js

111 lines
3.8 KiB
JavaScript
Raw Normal View History

2024-02-07 10:15:07 -06:00
const {join} = require('path');
2024-01-25 06:42:31 -06:00
2024-02-05 17:08:26 -06:00
const {version} = require('../package.json');
2024-02-07 10:15:07 -06:00
async function runtimeModule(compilation, flecks) {
const {compiler} = compilation;
2023-11-30 21:41:42 -06:00
// Inject flecks configuration.
2024-01-16 00:28:20 -06:00
const paths = Object.keys(flecks.flecks);
const resolvedPaths = (await Promise.all(
paths.map(async (path) => [path, await flecks.resolver.resolve(path)]),
))
.filter(([, resolved]) => resolved)
.map(([path]) => path);
2024-02-07 10:15:07 -06:00
const ymlPath = join(flecks.root, 'build', 'flecks.yml');
2024-01-22 09:16:07 -06:00
const runtime = {
2024-02-07 10:15:07 -06:00
/* eslint-disable indent */
bootstrappedConfig: JSON.stringify(flecks.invoke('@flecks/core.config')),
config: (`
2024-02-12 06:27:24 -06:00
Flecks.environmentConfiguration(
Flecks.dealiasedConfig(${
'production' === compiler.options.mode
? JSON.stringify(flecks.originalConfig)
: `require('${ymlPath}').default`
})
)
2024-02-07 10:15:07 -06:00
`),
/* eslint-enable indent */
2024-01-22 09:16:07 -06:00
loadFlecks: [
'async () => (',
' Object.fromEntries(',
' (await Promise.all(',
' [',
...resolvedPaths.map((path) => [
' (async () => {',
' try {',
2024-02-14 03:14:02 -06:00
` const M = await import('${path}');`,
' if (module.hot) {',
// Hooks for each fleck.
` module.hot.accept('${path}', async () => {`,
` const M = require('${path}')`,
' try {',
` global.flecks.refresh('${path}', M);`,
' }',
' catch (error) {',
// eslint-disable-next-line no-template-curly-in-string
' console.error(`HMR failed for fleck: ${error.message}`);',
' module.hot.invalidate();',
' }',
' });',
` return ['${path}', M];`,
' }',
2024-01-22 09:16:07 -06:00
' }',
' catch (error) {',
' if (!error.message.startsWith("Cannot find module")) {',
' throw error;',
' }',
' }',
' })(),',
]).flat(),
' ],',
' ))',
' .filter((entry) => entry),',
' )',
')',
].join('\n'),
2024-02-05 17:08:26 -06:00
version: JSON.stringify(version),
2024-01-22 09:16:07 -06:00
...await flecks.invokeAsync('@flecks/server.runtime'),
};
2024-02-14 03:14:02 -06:00
const renderedRuntime = `{${
2024-01-22 09:16:07 -06:00
Object.entries(runtime)
.map(([key, value]) => `"${key}": ${value}`).join(', ')
}}`;
2023-11-30 21:41:42 -06:00
const source = [
2024-02-12 06:27:24 -06:00
"const {Flecks} = require('@flecks/core');",
2023-11-30 21:41:42 -06:00
"process.env.FLECKS_CORE_BUILD_TARGET = 'server';",
2024-02-14 03:14:02 -06:00
`module.exports = (async () => (${renderedRuntime}))();`,
// HMR.
'if (module.hot) {',
` module.hot.accept('${ymlPath}', () => {`,
` const M = require('${ymlPath}').default;`,
' try {',
` global.flecks.invokeSequential('@flecks/core.hmr', '${ymlPath}', M);`,
' }',
' catch (error) {',
2024-02-06 08:16:53 -06:00
// eslint-disable-next-line no-template-curly-in-string
2024-02-14 03:14:02 -06:00
' console.error(`flecks.reload() failed: ${error.message}`);',
' module.hot.invalidate();',
' }',
' });',
// Keep HMR junk out of our output path.
' const {glob} = require("glob");',
' const {join} = require("path");',
' const {unlink} = require("fs/promises");',
' let previousHash = __webpack_hash__;',
' module.hot.addStatusHandler(async (status) => {',
' if ("idle" === status) {',
' const disposing = await glob(',
` join('${compiler.options.output.path}', \`*\${previousHash}.hot-update.*\`),`,
' );',
' await Promise.all(disposing.map((filename) => unlink(filename)));',
' previousHash = __webpack_hash__;',
' }',
' });',
'}',
];
2024-02-07 10:15:07 -06:00
// Create asset.
return source.join('\n');
}
exports.runtimeModule = runtimeModule;