I made a small library that can dynamically render OJS cells in the browser.
Did you consider using Notebook Kit for this? Itâs intended to support this type of usage. Hereâs an example:
Yes, but it was loading all the dependencies at start, while I expect it to only load them when a cell is using one.
I will later try to see if I can change it to be this way.
Yes, please let us know if you find a bug. I donât see it loading any unnecessary dependencies in the example notebook I linked above. (I do see it loading multiple copies of Acorn at different versions, but this is an unfortunate consequence of how jsDelivrâs module bundling is designed; youâd need an import map to coalesce the different versions into a single request.)
I started using notebook-kit and I have a few questions.
1. Updating a cell
I donât know if this way is correct or not.
const createCell = (cell) => {
const id = nextId++;
const select = document.createElement("select");
for (const type of ["ojs", "js", "ts", "html", "md", "tex", "dot"]) {
const option = document.createElement("option");
option.value = type;
option.textContent = type;
select.appendChild(option);
}
select.value = cell.mode;
const textarea = document.createElement("textarea");
textarea.value = cell?.value ?? "";
const run = document.createElement("button");
run.textContent = "Run";
const del = document.createElement("button");
del.textContent = "Delete";
const container = document.createElement("div");
const output = document.createElement("div");
container.appendChild(output);
const editor = document.createElement("div");
editor.append(select,textarea,run,del);
container.appendChild(editor);
main.appendChild(container);
const state = {
root: output,
variables: []
};
const execute = async () => {
cell.value = textarea.value;
cell.mode = select.value;
state.variables.forEach(v => {
v._observer = {};
v.delete();
});
state.variables = [];
try {
const definition = Kit.transpile(cell);
const body = compile(definition.body);
await runtime.define(
state,
{
...definition,
body
}
);
} catch (error) {
showError(output, error);
}
}
run.onclick = execute;
del.onclick = () => {
state.variables.forEach(v => {
v._observer = {};
v.delete();
});
container.remove();
cells.delete(id);
};
cells.set(id, {
state,
container
});
execute();
return id;
}