MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at mir/inline-method 145 lines 4.7 kB view raw
1import * as esbuild from 'esbuild'; 2import path from 'node:path'; 3import { writeFileSync } from 'node:fs'; 4 5function cString(input) { 6 return JSON.stringify(input); 7} 8 9function toSpecifier(rootDir, filePath) { 10 const relativePath = path.relative(rootDir, filePath).replaceAll('\\', '/'); 11 const withoutExt = relativePath.replace(/\.(cts|mts|ts|cjs|mjs|js)$/u, ''); 12 13 if (withoutExt.startsWith('node/')) { 14 return `node:${withoutExt.slice('node/'.length)}`; 15 } 16 17 if (withoutExt.startsWith('ant/')) { 18 return `ant:${withoutExt.slice('ant/'.length)}`; 19 } 20 21 throw new Error(`Unsupported builtin module path: ${relativePath}`); 22} 23 24function toAliasSpecifiers(specifier) { 25 if (specifier.startsWith('node:')) return [specifier.slice('node:'.length)]; 26 return []; 27} 28 29function toFormat(filePath) { 30 if (/\.(cts|cjs)$/u.test(filePath)) return 'MODULE_EVAL_FORMAT_CJS'; 31 if (/\.(mts|mjs)$/u.test(filePath)) return 'MODULE_EVAL_FORMAT_ESM'; 32 return 'MODULE_EVAL_FORMAT_UNKNOWN'; 33} 34 35async function bundleBuiltin(entryPath, format) { 36 const output = await esbuild.build({ 37 entryPoints: [entryPath], 38 bundle: true, 39 write: false, 40 minify: true, 41 platform: 'neutral', 42 format: format === 'MODULE_EVAL_FORMAT_ESM' ? 'esm' : 'cjs', 43 target: ['es2020'], 44 plugins: [ 45 { 46 name: 'builtin-externals', 47 setup(build) { 48 build.onResolve({ filter: /^(node:|ant:)/ }, args => ({ 49 path: args.path, 50 external: true 51 })); 52 } 53 } 54 ] 55 }); 56 57 if (output.outputFiles.length !== 1) { 58 throw new Error(`Expected exactly one bundled output for ${entryPath}`); 59 } 60 61 return output.outputFiles[0].contents; 62} 63 64function generateHeader(rootDir, bundles) { 65 const lines = []; 66 67 lines.push('/* Auto-generated builtin bundle data. DO NOT EDIT. */'); 68 lines.push(''); 69 lines.push('#ifndef ANT_BUILTIN_BUNDLE_DATA_H'); 70 lines.push('#define ANT_BUILTIN_BUNDLE_DATA_H'); 71 lines.push(''); 72 lines.push('#include <stddef.h>'); 73 lines.push('#include <stdint.h>'); 74 lines.push(''); 75 76 bundles.forEach((bundle, index) => { 77 const byteLines = []; 78 for (let i = 0; i < bundle.bytes.length; i += 16) { 79 byteLines.push(' ' + Array.from(bundle.bytes.slice(i, i + 16)).join(', ')); 80 } 81 82 lines.push(`/* ${bundle.specifier} <- ${path.relative(rootDir, bundle.entryPath).replaceAll('\\', '/')} */`); 83 lines.push(`static const uint8_t ant_builtin_bundle_${index}[] = {`); 84 lines.push(byteLines.join(',\n')); 85 lines.push('};'); 86 lines.push(''); 87 }); 88 89 lines.push('static const ant_builtin_bundle_module_t ant_builtin_bundle_modules[] = {'); 90 bundles.forEach((bundle, index) => { 91 lines.push(` { ant_builtin_bundle_${index}, sizeof(ant_builtin_bundle_${index}), ${bundle.format} },`); 92 }); 93 lines.push('};'); 94 lines.push(''); 95 lines.push('static const ant_builtin_bundle_alias_t ant_builtin_bundle_aliases[] = {'); 96 bundles.forEach((bundle, index) => { 97 for (const specifier of bundle.specifiers) { 98 lines.push(` { ${cString(specifier)}, ${specifier.length}, ${cString(bundle.specifier)}, ${index} },`); 99 } 100 }); 101 lines.push('};'); 102 lines.push(''); 103 lines.push('static const size_t ant_builtin_bundle_module_count ='); 104 lines.push(' sizeof(ant_builtin_bundle_modules) / sizeof(ant_builtin_bundle_modules[0]);'); 105 lines.push(''); 106 lines.push('static const size_t ant_builtin_bundle_alias_count ='); 107 lines.push(' sizeof(ant_builtin_bundle_aliases) / sizeof(ant_builtin_bundle_aliases[0]);'); 108 lines.push(''); 109 lines.push('#endif'); 110 111 return lines.join('\n') + '\n'; 112} 113 114async function main() { 115 const args = process.argv.slice(2); 116 if (args.length < 3) { 117 console.error(`Usage: ${process.argv[1]} <builtins-root> <output.h> <entry...>`); 118 process.exit(1); 119 } 120 121 const [builtinsRoot, outputFile, ...entryFiles] = args; 122 const bundles = []; 123 124 for (const entryPath of entryFiles) { 125 const specifier = toSpecifier(builtinsRoot, entryPath); 126 const format = toFormat(entryPath); 127 const bytes = await bundleBuiltin(entryPath, format); 128 const specifiers = [specifier, ...toAliasSpecifiers(specifier)]; 129 bundles.push({ entryPath, specifier, specifiers, format, bytes }); 130 } 131 132 const header = generateHeader(builtinsRoot, bundles); 133 const totalBundledBytes = bundles.reduce((sum, bundle) => sum + bundle.bytes.length, 0); 134 135 writeFileSync(outputFile, header); 136 137 console.log(`builtin bundle generated successfully: ${outputFile}`); 138 console.log(` bundled size: ${totalBundledBytes} bytes`); 139 console.log(` modules: ${bundles.length}`); 140} 141 142main().catch(error => { 143 console.error(error); 144 process.exit(1); 145});