Skip to content

Commit

Permalink
feat(Compilers): allow loading custom gleam modules
Browse files Browse the repository at this point in the history
  • Loading branch information
hatemhosny committed Apr 22, 2024
1 parent e87018f commit cf13102
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"Deploy",
"Import",
"ToolsPane",
"Modes"
"Modes",
"Import-maps"
]
}
1 change: 1 addition & 0 deletions src/livecodes/assets/templates/gleam.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 35 additions & 11 deletions src/livecodes/languages/gleam/lang-gleam-compiler.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable max-classes-per-file */
import type { CompilerFunction } from '../../models';
import { getLanguageCustomSettings } from '../utils';

(self as any).createGleamCompiler = (): CompilerFunction => {
const gleamBaseUrl = 'http://127.0.0.1:8081/';
const gleamBaseUrl = 'https://cdn.jsdelivr.net/gh/live-codes/gleam-precompiled@main/';
const compilerUrl = gleamBaseUrl + 'compiler/v1.1.0/gleam_wasm.js';
const srcBaseUrl = gleamBaseUrl + 'build/packages/';
const compiledBaseUrl = gleamBaseUrl + 'build/dev/javascript/';

Expand Down Expand Up @@ -48,18 +50,13 @@ import type { CompilerFunction } from '../../models';
'gleam/javascript/promise': {
srcUrl: srcBaseUrl + 'gleam_javascript/src/gleam/javascript/promise.gleam',
},
'hatem/mod/hello': {
src: `
@external(javascript, "./hatem/mod/hello.mjs", "hi")
pub fn hi(str: String) -> String
`,
compiledUrl:
'data:text/javascript;charset=UTF-8;base64,ZXhwb3J0IGNvbnN0IGhpID0gKHN0cikgPT4gJ2hpICcgKyBzdHI=',
'gleam/json': {
srcUrl: srcBaseUrl + 'gleam_json/src/gleam/json.gleam',
},
};

async function initGleamCompiler() {
const wasm = await import(gleamBaseUrl + 'wasm-compiler/gleam_wasm.js');
const wasm = await import(compilerUrl);
await wasm.default();
wasm.initialise_panic_hook(false);
if (!compiler) {
Expand Down Expand Up @@ -165,11 +162,35 @@ import type { CompilerFunction } from '../../models';
}),
);
};

const updateModules = async (newModules: Modules) => {
for (const mod of Object.keys(newModules)) {
const newModule = newModules[mod];
const oldModule = { ...modules[mod] };
modules[mod] = modules[mod] || {};
if (newModule.src) {
modules[mod].src = newModule.src;
}
if (newModule.srcUrl && newModule.srcUrl !== oldModule?.srcUrl) {
modules[mod].srcUrl = newModule.srcUrl;
modules[mod].src = undefined;
}
if (newModule.compiledUrl) {
modules[mod].compiledUrl = newModule.compiledUrl;
}
}
await loadModules(modules);
};

const compilerLoaded = Promise.all([initGleamCompiler(), loadModules(modules)]);

const compile = async (code: string) => {
const compile: CompilerFunction = async (code, { config }) => {
if (!code) return '';

await compilerLoaded;
const configModules: Modules = getLanguageCustomSettings('gleam', config)?.modules || {};
await updateModules(configModules);

const project = compiler.newProject();

for (const mod of Object.keys(modules)) {
Expand All @@ -182,6 +203,9 @@ import type { CompilerFunction } from '../../models';
project.compilePackage('javascript');
const js = project.readCompiledJavaScript('main');
return js.replace(/from\s+"\.\/(.+)"/g, (_: string, mod: string) => {
if (mod === 'gleam.mjs') {
return `from "${compiledBaseUrl}prelude.mjs"`;
}
if (mod.startsWith('gleam/')) {
const dir = mod.startsWith('gleam/javascript') ? 'gleam_javascript/' : 'gleam_stdlib/';
return `from "${compiledBaseUrl + dir + mod}"`;
Expand All @@ -190,7 +214,7 @@ import type { CompilerFunction } from '../../models';
if (modules[modName]?.compiledUrl) {
return `from "${modules[modName].compiledUrl}"`;
}
return `from "${modName}"`;
return `from "${mod}"`;
});
} catch (error) {
// eslint-disable-next-line no-console
Expand Down

0 comments on commit cf13102

Please sign in to comment.