mirror of
https://github.com/CompeyDev/bun-lune-loader.git
synced 2024-12-12 12:50:39 +00:00
feat: include initial implementation
This commit is contained in:
parent
4d9ebaaa6e
commit
f3d2226910
5 changed files with 165 additions and 0 deletions
6
examples/data.luau
Normal file
6
examples/data.luau
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
return {
|
||||||
|
SomeData = {
|
||||||
|
"This is string data",
|
||||||
|
69
|
||||||
|
}
|
||||||
|
}
|
3
examples/run.ts
Normal file
3
examples/run.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { SomeData } from "./data.luau";
|
||||||
|
|
||||||
|
console.log("Received data: ", SomeData)
|
19
src/index.ts
Normal file
19
src/index.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { BunPlugin } from "bun";
|
||||||
|
|
||||||
|
const plugin: BunPlugin = {
|
||||||
|
name: "lune",
|
||||||
|
async setup(build) {
|
||||||
|
const { importPath } = await import("./loader");
|
||||||
|
|
||||||
|
build.onLoad({ filter: /\.(luau|lua)$/ }, (args) => {
|
||||||
|
const mod = importPath(args.path);
|
||||||
|
|
||||||
|
return {
|
||||||
|
contents: mod,
|
||||||
|
loader: "json",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default plugin;
|
41
src/loader.luau
Normal file
41
src/loader.luau
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
local process = require("@lune/process")
|
||||||
|
local jsonEncode = require("@lune/net").jsonEncode
|
||||||
|
|
||||||
|
local possibleErrors = {
|
||||||
|
FILE_NOT_FOUND = "No file exist at the path",
|
||||||
|
NOT_A_MODULE = "Module must return at least one value"
|
||||||
|
}
|
||||||
|
|
||||||
|
local _, resolvedMod = xpcall(function()
|
||||||
|
-- [1] - Path to import
|
||||||
|
-- [2] - Whether module import or not
|
||||||
|
|
||||||
|
local mod = require(process.args[1])
|
||||||
|
|
||||||
|
if process.args[2] == "MODULE" and mod == nil then
|
||||||
|
error(possibleErrors.NOT_A_MODULE)
|
||||||
|
end
|
||||||
|
|
||||||
|
return mod
|
||||||
|
end, function(err)
|
||||||
|
-- We only need the msg, not trace
|
||||||
|
local errMsg = tostring(err):split("stack traceback:")[1]
|
||||||
|
|
||||||
|
for id, msg in possibleErrors do
|
||||||
|
if errMsg:match(msg) then
|
||||||
|
print(`[bun-loader-lune::ImportError::{id}] ` .. errMsg)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("-- [ImportError] --")
|
||||||
|
print(tostring(err))
|
||||||
|
end)
|
||||||
|
|
||||||
|
if process.args[2] == "MODULE" and typeof(resolvedMod) == "table" then
|
||||||
|
local modReprJson = jsonEncode(resolvedMod)
|
||||||
|
|
||||||
|
print("--start @generated JS compatible object--")
|
||||||
|
print(modReprJson)
|
||||||
|
print("--end @generated JS compatible object--")
|
||||||
|
end
|
96
src/loader.ts
Normal file
96
src/loader.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// We need to grab x.luau, then pass the return values of that to another
|
||||||
|
// function in the luau side. This function parses the table and converts
|
||||||
|
// it to a JSON object that we can then parse and serve back to the user.
|
||||||
|
|
||||||
|
import { spawnSync, which } from "bun";
|
||||||
|
import { exit } from "process";
|
||||||
|
|
||||||
|
// - Execute lune and run loader script with args for source code
|
||||||
|
// - return JSON
|
||||||
|
|
||||||
|
export function importPath(path: PathLike): string {
|
||||||
|
const lunePath = which("lune");
|
||||||
|
|
||||||
|
if (!lunePath) {
|
||||||
|
throw new Error(
|
||||||
|
"[bun-plugin-lune::loader] Cannot find `lune` executable in path",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path to luau loader probs shouldnt be hardcoded
|
||||||
|
const luneChild = spawnSync({
|
||||||
|
cmd: [lunePath, "./loader.luau", path.toString(), "MODULE"],
|
||||||
|
cwd: import.meta.dir,
|
||||||
|
onExit(_proc, exitCode, _sigCode, err) {
|
||||||
|
if (exitCode != 0 && exitCode != null) {
|
||||||
|
console.warn(
|
||||||
|
`[bun-plugin-lune::loader] \`lune\` process exited with code ${exitCode}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
err
|
||||||
|
? () => {
|
||||||
|
console.warn(
|
||||||
|
"[bun-plugin-lune::loader] Internal error: ",
|
||||||
|
err.message,
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stderr: "pipe",
|
||||||
|
stdout: "pipe",
|
||||||
|
});
|
||||||
|
|
||||||
|
const luneStderr = luneChild.stderr.toString();
|
||||||
|
|
||||||
|
if (luneStderr != "") {
|
||||||
|
const fmtTrace = luneStderr.split("\n")
|
||||||
|
.map((l) => l = " " + l).join("");
|
||||||
|
|
||||||
|
console.warn("\nTRACE:");
|
||||||
|
console.warn(fmtTrace, "\n");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let luneStdout = luneChild.stdout.toString().split("\n");
|
||||||
|
let generatedJSONObject: string;
|
||||||
|
|
||||||
|
// luneStdout format:
|
||||||
|
// ...logs n' stuff
|
||||||
|
// --start @generated JS compatible object--
|
||||||
|
// ...object -- Always is in one line
|
||||||
|
// --end @generated JS compatible object--
|
||||||
|
// Additional newline (\n)
|
||||||
|
|
||||||
|
// Remove the last empty padding newline
|
||||||
|
luneStdout = luneStdout.filter((v) => v != "");
|
||||||
|
luneStdout.every((l, n) => {
|
||||||
|
// If the stdout line doesn't start with `--`, that means
|
||||||
|
// it must be a log, and not the generated output
|
||||||
|
if (l.startsWith("--")) {
|
||||||
|
if (
|
||||||
|
l == "--start @generated JS compatible object--" &&
|
||||||
|
luneStdout[n + 2] == "--end @generated JS compatible object--"
|
||||||
|
) {
|
||||||
|
// The third last index is the end of the generated object
|
||||||
|
// The next index is the start of the generated object, after the comment
|
||||||
|
generatedJSONObject = luneStdout.slice(n + 1, n + 2)[0];
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(
|
||||||
|
"[bun-plugin-lune::loader] invalid JS object returned by internal loader.",
|
||||||
|
);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
} else if (process.env.NODE_ENV == "dev") {
|
||||||
|
console.log(l);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return generatedJSONObject!;
|
||||||
|
}
|
Loading…
Reference in a new issue