Re-enable jsaddle

This commit is contained in:
Ryan Trinkle 2023-07-06 16:55:31 -04:00
parent fbb6eab003
commit 2544e43b68

View File

@ -1,6 +1,7 @@
const child_process = require('node:child_process');
const path = require('path');
const readFileSync = require('fs').readFileSync;
const http = require('http');
module.exports = function(source) {
const options = this.getOptions();
@ -9,48 +10,26 @@ module.exports = function(source) {
const cabalFileDir = path.dirname(cabalFilePath);
if (options.dev) {
this.cacheable(false);
if (options.isServer) {
run_jsaddle_warp(callback, cabalFilePath, cabalFileDir);
} else {
connect_to_jsaddle_warp(callback, cabalFilePath, cabalFileDir);
}
} else {
if(options.isServer) {
// no-op
callback(null, '');
} else {
ghcjs_build(callback, cabalFilePath, cabalFileDir);
}
}
}
function ghcjs_build(callback, cabalFilePath, cabalFileDir) {
let result;
try {
//TODO: re-enable jsaddle loading
if (false && options.dev) {
if (options.isServer) {
// no-op
result = 'export function haskellEngine(arg, global) { };';
} else { // !options.isServer
this.cacheable(false);
const command = 'ghcid -r -W -c"cabal repl ' + path.basename(cabalFilePath) + '"';
const ghcid_process = child_process.spawn(
'nix-shell',
['-A', 'shells.ghc', '--run', command],
{
cwd: cabalFileDir,
stdio: 'inherit',
}
);
// ghcid_process should not stop
ghcid_process.on('close', (code) => {
throw("ghcid process stopped");
});
// TODO: we should ideally wait for the ghcid to successfully start the jsaddle server
//TODO: xhr.onerror
result =
'import * as react from "react";' +
'console.log("retrieving jsaddle.js");' +
'const jsaddleRoot = "http://localhost:3001";' +
'const xhr = new XMLHttpRequest();' +
'xhr.open("GET", jsaddleRoot + "/jsaddle.js");' +
'var result;' +
'xhr.onload = () => {' +
' eval("(function(JSADDLE_ROOT, arg, global) {" + xhr.response + "})")(jsaddleRoot, { react, setVal: (v) => { result = v; } }, window);' +
'};' +
'xhr.send();';
}
} else { // !options.dev
if(options.isServer) {
// no-op
result = '';
} else {
//TODO: Correctly report dependencies
const build_command = 'js-unknown-ghcjs-cabal build ' + path.basename(cabalFilePath);
const build_result = child_process.spawnSync(
@ -99,8 +78,6 @@ module.exports = function(source) {
}
result = "import * as react from 'react'; function haskellEngine(arg, global) { function getProgramArg() { return arg; };" + syncMainJs + "}; var result; haskellEngine({ react, setVal: (v) => { result = v; } }, window); export default result;";
}
}
} catch (error) {
callback(error);
return;
@ -108,3 +85,74 @@ module.exports = function(source) {
callback(null, result);
}
function run_jsaddle_warp(callback, cabalFilePath, cabalFileDir) {
let result;
try {
const command = 'ghcid -r -W -c"cabal repl ' + path.basename(cabalFilePath) + '"';
const ghcid_process = child_process.spawn(
'nix-shell',
['-A', 'shells.ghc', '--run', command],
{
cwd: cabalFileDir,
stdio: 'inherit',
}
);
// ghcid_process should not stop
ghcid_process.on('close', (code) => {
throw("ghcid process stopped");
});
// no-op
result = '';
} catch (error) {
callback(error);
return;
}
callback(null, result);
}
function connect_to_jsaddle_warp(callback, cabalFilePath, cabalFileDir) {
let retry_till_warp_is_up = function () {
const JSADDLE_ROOT = "http://0.0.0.0:3001";
try {
let request = http.get(JSADDLE_ROOT + '/jsaddle.js', (res) => {
if (res.statusCode !== 200) {
res.resume();
callback(`Did not get an OK from the jsaddle-warp. Code: ${res.statusCode}.`);
return;
}
// Somehow reading the data from this request and injecting it into the
// result causes webpack to complain. So we do an additional XHR on the
// browser to get the jsaddle.js
let result =
'import * as react from "react";' +
'var result = null;' +
'function runJsaddleAndInitResult() {' +
' const JSADDLE_ROOT = "http://localhost:3001";' +
' const xhr = new XMLHttpRequest();' +
' xhr.open("GET", JSADDLE_ROOT + "/jsaddle.js", false);' +
' xhr.send();' +
' var dontAutoConnectWebsocket = true;' +
' var arg = { react, setVal: (v) => { result = v; } };' +
' eval(xhr.responseText + "; var {connId, core, processReqsViaXHR} = connectXHR(); while(result == null) { processReqsViaXHR();}; connectWebsocket({core, connId});");' +
'}' +
'runJsaddleAndInitResult();' +
'export default result;';
callback(null, result);
return;
});
request.on('error', (err) => {
console.error(`Did not get a response from the jsaddle-warp. Retrying. Error: ${err}.`);
setTimeout(retry_till_warp_is_up, 2000);
return;
});
} catch (error) {
callback(error);
return;
}
};
retry_till_warp_is_up();
}