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.

use environment variables for Ant metadata

+38 -115
+1 -1
meson.build
··· 96 96 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 97 97 98 98 version_conf = configuration_data() 99 - version_conf.set('ANT_VERSION', '0.3.3.6') 99 + version_conf.set('ANT_VERSION', '0.3.3.7') 100 100 version_conf.set('ANT_GIT_HASH', git_hash) 101 101 version_conf.set('ANT_BUILD_DATE', build_date) 102 102
+3 -3
src/core/ant.ts
··· 1 - Ant.version = '{{VERSION}}'; 2 - Ant.revision = '{{GIT_HASH}}'; 3 - Ant.buildDate = '{{BUILD_DATE}}'; 1 + Ant.version = import.meta.env.VERSION; 2 + Ant.revision = import.meta.env.GIT_HASH; 3 + Ant.buildDate = import.meta.env.BUILD_DATE; 4 4 5 5 Ant.typeof = function (t) { 6 6 const value = Ant.raw.typeof(t);
+1 -1
src/core/index.ts
··· 1 - snapshot_inline('./ant.ts'); 1 + import './ant.ts';
+21 -101
src/tools/gen_snapshot.js
··· 1 1 import * as esbuild from 'esbuild'; 2 - import { dirname, resolve } from 'node:path'; 3 - import { readFileSync, writeFileSync } from 'node:fs'; 4 - 5 - const processedModules = new Set(); 6 - 7 - function wrapModule(content) { 8 - const exports = []; 9 - let output = '(function() {\n'; 10 - 11 - const exportRegex = /export\s+(const|let|var|function)\s+(\w+)/g; 12 - let match; 13 - let lastIndex = 0; 14 - let processed = ''; 15 - 16 - while ((match = exportRegex.exec(content)) !== null) { 17 - processed += content.slice(lastIndex, match.index); 18 - processed += `${match[1]} ${match[2]}`; 19 - exports.push(match[2]); 20 - lastIndex = match.index + match[0].length; 21 - } 22 - 23 - processed += content.slice(lastIndex); 24 - output += processed; 25 - 26 - if (exports.length > 0) { 27 - output += `\nreturn { ${exports.join(', ')} };\n})()`; 28 - } else output += '})()'; 29 - 30 - return output; 31 - } 32 - 33 - function processInlines(filePath, content) { 34 - const dir = dirname(filePath); 35 - 36 - return content.replace(/snapshot_inline\s*\(\s*['"](.+?)['"]\s*\);?/g, (_, importPath) => { 37 - const resolved = resolve(dir, importPath); 38 - 39 - try { 40 - return readFileSync(resolved, 'utf-8'); 41 - } catch (err) { 42 - throw Error(`Error: Cannot read inline file: ${resolved}`); 43 - } 44 - }); 45 - } 46 - 47 - function processIncludes(filePath, content) { 48 - const dir = dirname(filePath); 49 - 50 - return content.replace(/snapshot_include\s*\(\s*['"](.+?)['"]\s*\)/g, (_, importPath) => { 51 - const resolved = resolve(dir, importPath); 52 - 53 - if (processedModules.has(resolved)) { 54 - console.error(`Warning: Circular dependency detected: ${resolved}`); 55 - return ''; 56 - } 57 - 58 - processedModules.add(resolved); 59 - 60 - try { 61 - let moduleContent = readFileSync(resolved, 'utf-8'); 62 - moduleContent = processIncludes(resolved, moduleContent); 63 - return wrapModule(moduleContent); 64 - } catch (err) { 65 - throw Error(`Error: Cannot read module: ${resolved}`); 66 - } 67 - }); 68 - } 2 + import { writeFileSync } from 'node:fs'; 69 3 70 4 function replaceTemplates(content, replacements) { 71 5 for (const [key, value] of Object.entries(replacements)) { ··· 74 8 return content; 75 9 } 76 10 77 - function generateHeader(inputFile, data) { 78 - const bytes = [...Buffer.from(data)].map(b => `0x${b.toString(16).padStart(2, '0')}`); 79 - 11 + function generateHeader(inputFile, bytes) { 80 12 const lines = []; 81 13 for (let i = 0; i < bytes.length; i += 16) { 82 14 lines.push(' ' + bytes.slice(i, i + 16).join(', ')); ··· 95 27 ${lines.join(',\n')} 96 28 }; 97 29 98 - static const size_t ant_snapshot_source_len = ${data.length}; 99 - 100 - /* bundled source size: ${data.length} bytes */ 101 - static const size_t ant_snapshot_mem_size = ${data.length}; 30 + /* bundled source size: ${bytes.length} bytes */ 31 + static const size_t ant_snapshot_source_len = ${bytes.length}; 102 32 103 33 #endif /* ANT_SNAPSHOT_DATA_H */ 104 34 `; ··· 113 43 process.exit(1); 114 44 } 115 45 116 - const [inputFile, outputFile, ...replacementArgs] = args; 46 + const [inputFile, outputFile, ...rawArgs] = args; 117 47 118 - const replacements = {}; 119 - for (const arg of replacementArgs) { 120 - const idx = arg.indexOf('='); 121 - if (idx !== -1) { 122 - const key = arg.slice(0, idx); 123 - const value = arg.slice(idx + 1); 124 - replacements[key] = value; 125 - console.log(`template replacement: {{${key}}} -> ${value}`); 126 - } 127 - } 48 + const replacements = rawArgs.reduce((acc, arg) => { 49 + const pivot = arg.indexOf('='); 50 + if (pivot === -1) return acc; 128 51 129 - let content; 130 - try { 131 - content = readFileSync(inputFile, 'utf-8'); 132 - } catch (err) { 133 - throw Error(`Error: Cannot open input file: ${inputFile}`); 134 - } 52 + const key = arg.slice(0, pivot); 53 + const value = arg.slice(pivot + 1); 135 54 136 - const originalSize = content.length; 137 - 138 - content = processInlines(inputFile, content); 139 - content = processIncludes(inputFile, content); 140 - content = replaceTemplates(content, replacements); 55 + acc[`import.meta.env.${key}`] = JSON.stringify(value); 56 + return acc; 57 + }, {}); 141 58 142 - const result = await esbuild.transform(content, { 59 + const result = await esbuild.build({ 143 60 minify: true, 144 - loader: 'ts' 61 + bundle: true, 62 + write: false, 63 + format: 'esm', 64 + define: replacements, 65 + entryPoints: [inputFile] 145 66 }); 146 67 147 - const minified = result.code.trimEnd(); 148 - console.log(minified); 68 + const minified = result.outputFiles[0].contents; 69 + console.log(new TextDecoder().decode(minified)); 149 70 150 71 const header = generateHeader(inputFile, minified); 151 72 writeFileSync(outputFile, header); 152 73 153 74 console.log(`snapshot generated successfully: ${outputFile}`); 154 - console.log(` original size: ${originalSize} bytes`); 155 75 console.log(` bundled size: ${minified.length} bytes`); 156 76 console.log(` replacements: ${Object.keys(replacements).length}`); 157 77 }
-3
src/types/ant.d.ts
··· 68 68 } 69 69 70 70 declare const Ant: AntStatic; 71 - 72 - export = Ant; 73 - export as namespace Ant;
+3 -2
src/types/snapshot.d.ts
··· 1 - declare function snapshot_inline(path: string): void; 2 - declare function snapshot_include(path: string): unknown; 1 + interface ImportMeta { 2 + readonly env: { [key: string]: string }; 3 + }
+9 -4
tsconfig.json
··· 1 1 { 2 2 "compilerOptions": { 3 - "lib": ["dom", "ES2017"], 4 - "typeRoots": ["./node_modules/@types"] 3 + "noEmit": true, 4 + "strict": true, 5 + 6 + "target": "ES2024", 7 + "module": "ESNext", 8 + "moduleResolution": "bundler", 9 + "lib": ["ES2024", "DOM", "DOM.Iterable"], 10 + "typeRoots": ["./node_modules/@types", "./src/types"] 5 11 }, 6 - 7 - "include": ["src/types/*.d.ts", "src/core/**/*"] 12 + "include": ["src/types/**/*.d.ts", "src/core/**/*"] 8 13 }